ARM: Make GIC function that should only be called by GIC protected.
[gem5.git] / src / dev / etherlink.cc
index 8c54da67890bd506cb7c497f6ff06b6f34485ccb..289b7454342b659c725a76bb259daed492ce8288 100644 (file)
 
 #include "base/random.hh"
 #include "base/trace.hh"
+#include "debug/Ethernet.hh"
+#include "debug/EthernetData.hh"
 #include "dev/etherdump.hh"
 #include "dev/etherint.hh"
 #include "dev/etherlink.hh"
 #include "dev/etherpkt.hh"
 #include "params/EtherLink.hh"
+#include "sim/core.hh"
 #include "sim/serialize.hh"
 #include "sim/system.hh"
-#include "sim/core.hh"
 
 using namespace std;
 
-EtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1,
-                     double rate, Tick delay, Tick delayVar, EtherDump *dump)
-    : SimObject(name)
+EtherLink::EtherLink(const Params *p)
+    : EtherObject(p)
 {
-    link[0] = new Link(name + ".link0", this, 0, rate, delay, delayVar, dump);
-    link[1] = new Link(name + ".link1", this, 1, rate, delay, delayVar, dump);
-
-    interface[0] = new Interface(name + ".int0", link[0], link[1]);
-    interface[1] = new Interface(name + ".int1", link[1], link[0]);
+    link[0] = new Link(name() + ".link0", this, 0, p->speed,
+                       p->delay, p->delay_var, p->dump);
+    link[1] = new Link(name() + ".link1", this, 1, p->speed,
+                       p->delay, p->delay_var, p->dump);
 
-    interface[0]->setPeer(peer0);
-    peer0->setPeer(interface[0]);
-    interface[1]->setPeer(peer1);
-    peer1->setPeer(interface[1]);
+    interface[0] = new Interface(name() + ".int0", link[0], link[1]);
+    interface[1] = new Interface(name() + ".int1", link[1], link[0]);
 }
 
+
 EtherLink::~EtherLink()
 {
     delete link[0];
@@ -76,6 +75,23 @@ EtherLink::~EtherLink()
     delete interface[1];
 }
 
+EtherInt*
+EtherLink::getEthPort(const std::string &if_name, int idx)
+{
+    Interface *i;
+    if (if_name == "int0")
+        i = interface[0];
+    else if (if_name == "int1")
+        i = interface[1];
+    else
+        return NULL;
+    if (i->getPeer())
+        panic("interface already connected to\n");
+
+    return i;
+}
+
+
 EtherLink::Interface::Interface(const string &name, Link *tx, Link *rx)
     : EtherInt(name), txlink(tx)
 {
@@ -121,7 +137,7 @@ class LinkDelayEvent : public Event
   public:
     // non-scheduling version for createForUnserialize()
     LinkDelayEvent();
-    LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt, Tick when);
+    LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt);
 
     void process();
 
@@ -139,7 +155,8 @@ EtherLink::Link::txDone()
 
     if (linkDelay > 0) {
         DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay);
-        new LinkDelayEvent(this, packet, curTick + linkDelay);
+        Event *event = new LinkDelayEvent(this, packet);
+        parent->schedule(event, curTick() + linkDelay);
     } else {
         txComplete(packet);
     }
@@ -163,13 +180,12 @@ EtherLink::Link::transmit(EthPacketPtr pkt)
 
     packet = pkt;
     Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0);
-    if (delayVar != 0) {
-        Random<Tick> var;
-        delay +=  var.uniform(0, delayVar);
-    }
+    if (delayVar != 0)
+        delay += random_mt.random<Tick>(0, delayVar);
+
     DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
             delay, ticksPerByte);
-    doneEvent.schedule(curTick + delay);
+    parent->schedule(doneEvent, curTick() + delay);
 
     return true;
 }
@@ -207,23 +223,22 @@ EtherLink::Link::unserialize(const string &base, Checkpoint *cp,
     if (event_scheduled) {
         Tick event_time;
         paramIn(cp, section, base + ".event_time", event_time);
-        doneEvent.schedule(event_time);
+        parent->schedule(doneEvent, event_time);
     }
 }
 
 LinkDelayEvent::LinkDelayEvent()
-    : Event(&mainEventQueue), link(NULL)
+    : link(NULL)
 {
     setFlags(AutoSerialize);
     setFlags(AutoDelete);
 }
 
-LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, EthPacketPtr p, Tick when)
-    : Event(&mainEventQueue), link(l), packet(p)
+LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, EthPacketPtr p)
+    : link(l), packet(p)
 {
     setFlags(AutoSerialize);
     setFlags(AutoDelete);
-    schedule(when);
 }
 
 void
@@ -275,5 +290,5 @@ REGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent)
 EtherLink *
 EtherLinkParams::create()
 {
-    return new EtherLink(name, int1, int2, speed, delay, delay_var, dump);
+    return new EtherLink(this);
 }