etherlink.cc revision 2665
17639Sgblack@eecs.umich.edu/*
27639Sgblack@eecs.umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan
310037SARM gem5 Developers * All rights reserved.
47639Sgblack@eecs.umich.edu *
57639Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
67639Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
77639Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
87639Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
97639Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
107639Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
117639Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
127639Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
137639Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
147639Sgblack@eecs.umich.edu * this software without specific prior written permission.
157639Sgblack@eecs.umich.edu *
167639Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177639Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187639Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197639Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207639Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
217639Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
227639Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237639Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247639Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257639Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
267639Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277639Sgblack@eecs.umich.edu *
287639Sgblack@eecs.umich.edu * Authors: Nathan Binkert
297639Sgblack@eecs.umich.edu *          Ron Dreslinski
307639Sgblack@eecs.umich.edu */
317639Sgblack@eecs.umich.edu
327639Sgblack@eecs.umich.edu/* @file
337639Sgblack@eecs.umich.edu * Device module for modelling a fixed bandwidth full duplex ethernet link
347639Sgblack@eecs.umich.edu */
357639Sgblack@eecs.umich.edu
367639Sgblack@eecs.umich.edu#include <cmath>
377639Sgblack@eecs.umich.edu#include <deque>
387639Sgblack@eecs.umich.edu#include <string>
397639Sgblack@eecs.umich.edu#include <vector>
407639Sgblack@eecs.umich.edu
417639Sgblack@eecs.umich.edu#include "base/random.hh"
427639Sgblack@eecs.umich.edu#include "base/trace.hh"
437639Sgblack@eecs.umich.edu#include "dev/etherdump.hh"
447639Sgblack@eecs.umich.edu#include "dev/etherint.hh"
457639Sgblack@eecs.umich.edu#include "dev/etherlink.hh"
467639Sgblack@eecs.umich.edu#include "dev/etherpkt.hh"
477639Sgblack@eecs.umich.edu#include "sim/builder.hh"
487639Sgblack@eecs.umich.edu#include "sim/serialize.hh"
497639Sgblack@eecs.umich.edu#include "sim/system.hh"
507639Sgblack@eecs.umich.edu#include "sim/root.hh"
517639Sgblack@eecs.umich.edu
527639Sgblack@eecs.umich.eduusing namespace std;
537639Sgblack@eecs.umich.edu
547639Sgblack@eecs.umich.eduEtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1,
557639Sgblack@eecs.umich.edu                     double rate, Tick delay, Tick delayVar, EtherDump *dump)
567639Sgblack@eecs.umich.edu    : SimObject(name)
577639Sgblack@eecs.umich.edu{
587639Sgblack@eecs.umich.edu    link[0] = new Link(name + ".link0", this, 0, rate, delay, delayVar, dump);
597639Sgblack@eecs.umich.edu    link[1] = new Link(name + ".link1", this, 1, rate, delay, delayVar, dump);
607639Sgblack@eecs.umich.edu
617639Sgblack@eecs.umich.edu    interface[0] = new Interface(name + ".int0", link[0], link[1]);
627639Sgblack@eecs.umich.edu    interface[1] = new Interface(name + ".int1", link[1], link[0]);
637639Sgblack@eecs.umich.edu
647639Sgblack@eecs.umich.edu    interface[0]->setPeer(peer0);
657639Sgblack@eecs.umich.edu    peer0->setPeer(interface[0]);
667639Sgblack@eecs.umich.edu    interface[1]->setPeer(peer1);
677639Sgblack@eecs.umich.edu    peer1->setPeer(interface[1]);
687639Sgblack@eecs.umich.edu}
697639Sgblack@eecs.umich.edu
707639Sgblack@eecs.umich.eduEtherLink::~EtherLink()
717639Sgblack@eecs.umich.edu{
727639Sgblack@eecs.umich.edu    delete link[0];
737639Sgblack@eecs.umich.edu    delete link[1];
747639Sgblack@eecs.umich.edu
757639Sgblack@eecs.umich.edu    delete interface[0];
767639Sgblack@eecs.umich.edu    delete interface[1];
777639Sgblack@eecs.umich.edu}
787639Sgblack@eecs.umich.edu
797639Sgblack@eecs.umich.eduEtherLink::Interface::Interface(const string &name, Link *tx, Link *rx)
807639Sgblack@eecs.umich.edu    : EtherInt(name), txlink(tx)
817639Sgblack@eecs.umich.edu{
827639Sgblack@eecs.umich.edu    tx->setTxInt(this);
837639Sgblack@eecs.umich.edu    rx->setRxInt(this);
847639Sgblack@eecs.umich.edu}
857639Sgblack@eecs.umich.edu
867639Sgblack@eecs.umich.eduEtherLink::Link::Link(const string &name, EtherLink *p, int num,
877639Sgblack@eecs.umich.edu                      double rate, Tick delay, Tick delay_var, EtherDump *d)
887639Sgblack@eecs.umich.edu    : objName(name), parent(p), number(num), txint(NULL), rxint(NULL),
897639Sgblack@eecs.umich.edu      ticksPerByte(rate), linkDelay(delay), delayVar(delay_var), dump(d),
907639Sgblack@eecs.umich.edu      doneEvent(this)
917639Sgblack@eecs.umich.edu{ }
927639Sgblack@eecs.umich.edu
937639Sgblack@eecs.umich.eduvoid
947639Sgblack@eecs.umich.eduEtherLink::serialize(ostream &os)
957639Sgblack@eecs.umich.edu{
967639Sgblack@eecs.umich.edu    link[0]->serialize("link0", os);
9710037SARM gem5 Developers    link[1]->serialize("link1", os);
9810037SARM gem5 Developers}
997639Sgblack@eecs.umich.edu
1007639Sgblack@eecs.umich.eduvoid
1017639Sgblack@eecs.umich.eduEtherLink::unserialize(Checkpoint *cp, const string &section)
1027639Sgblack@eecs.umich.edu{
1037639Sgblack@eecs.umich.edu    link[0]->unserialize("link0", cp, section);
1047639Sgblack@eecs.umich.edu    link[1]->unserialize("link1", cp, section);
1057639Sgblack@eecs.umich.edu}
1067639Sgblack@eecs.umich.edu
1077639Sgblack@eecs.umich.eduvoid
1087639Sgblack@eecs.umich.eduEtherLink::Link::txComplete(EthPacketPtr packet)
1097639Sgblack@eecs.umich.edu{
1107639Sgblack@eecs.umich.edu    DPRINTF(Ethernet, "packet received: len=%d\n", packet->length);
1117639Sgblack@eecs.umich.edu    DDUMP(EthernetData, packet->data, packet->length);
1127639Sgblack@eecs.umich.edu    rxint->sendPacket(packet);
1137639Sgblack@eecs.umich.edu}
1147639Sgblack@eecs.umich.edu
11510037SARM gem5 Developersclass LinkDelayEvent : public Event
11610037SARM gem5 Developers{
1177639Sgblack@eecs.umich.edu  protected:
1187639Sgblack@eecs.umich.edu    EtherLink::Link *link;
1197639Sgblack@eecs.umich.edu    EthPacketPtr packet;
1207639Sgblack@eecs.umich.edu
1217639Sgblack@eecs.umich.edu  public:
1227639Sgblack@eecs.umich.edu    // non-scheduling version for createForUnserialize()
1237639Sgblack@eecs.umich.edu    LinkDelayEvent();
1247639Sgblack@eecs.umich.edu    LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt, Tick when);
1257639Sgblack@eecs.umich.edu
1267639Sgblack@eecs.umich.edu    void process();
1277639Sgblack@eecs.umich.edu
1287639Sgblack@eecs.umich.edu    virtual void serialize(ostream &os);
1297639Sgblack@eecs.umich.edu    virtual void unserialize(Checkpoint *cp, const string &section);
1307639Sgblack@eecs.umich.edu    static Serializable *createForUnserialize(Checkpoint *cp,
1317639Sgblack@eecs.umich.edu                                              const string &section);
13210037SARM gem5 Developers};
13310037SARM gem5 Developers
13410037SARM gem5 Developersvoid
13510037SARM gem5 DevelopersEtherLink::Link::txDone()
13610037SARM gem5 Developers{
13710037SARM gem5 Developers    if (dump)
13810037SARM gem5 Developers        dump->dump(packet);
13910037SARM gem5 Developers
14010037SARM gem5 Developers    if (linkDelay > 0) {
14110037SARM gem5 Developers        DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay);
14210037SARM gem5 Developers        new LinkDelayEvent(this, packet, curTick + linkDelay);
14310037SARM gem5 Developers    } else {
14410037SARM gem5 Developers        txComplete(packet);
14510037SARM gem5 Developers    }
14610037SARM gem5 Developers
14710037SARM gem5 Developers    packet = 0;
14810037SARM gem5 Developers    assert(!busy());
14910037SARM gem5 Developers
15010037SARM gem5 Developers    txint->sendDone();
15110037SARM gem5 Developers}
15210037SARM gem5 Developers
15310037SARM gem5 Developersbool
15410037SARM gem5 DevelopersEtherLink::Link::transmit(EthPacketPtr pkt)
15510037SARM gem5 Developers{
15610037SARM gem5 Developers    if (busy()) {
15710037SARM gem5 Developers        DPRINTF(Ethernet, "packet not sent, link busy\n");
15810037SARM gem5 Developers        return false;
15910037SARM gem5 Developers    }
16010037SARM gem5 Developers
16110037SARM gem5 Developers    DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length);
16210037SARM gem5 Developers    DDUMP(EthernetData, pkt->data, pkt->length);
16310037SARM gem5 Developers
1647639Sgblack@eecs.umich.edu    packet = pkt;
1657639Sgblack@eecs.umich.edu    Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0);
1667639Sgblack@eecs.umich.edu    if (delayVar != 0) {
1677639Sgblack@eecs.umich.edu        Random<Tick> var;
1687639Sgblack@eecs.umich.edu        delay +=  var.uniform(0, delayVar);
1697639Sgblack@eecs.umich.edu    }
1707639Sgblack@eecs.umich.edu    DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
1717639Sgblack@eecs.umich.edu            delay, ticksPerByte);
1727639Sgblack@eecs.umich.edu    doneEvent.schedule(curTick + delay);
1737639Sgblack@eecs.umich.edu
1747639Sgblack@eecs.umich.edu    return true;
1757639Sgblack@eecs.umich.edu}
1767639Sgblack@eecs.umich.edu
1777639Sgblack@eecs.umich.eduvoid
1787639Sgblack@eecs.umich.eduEtherLink::Link::serialize(const string &base, ostream &os)
1797639Sgblack@eecs.umich.edu{
1807639Sgblack@eecs.umich.edu    bool packet_exists = packet;
1817639Sgblack@eecs.umich.edu    paramOut(os, base + ".packet_exists", packet_exists);
1827639Sgblack@eecs.umich.edu    if (packet_exists)
1837639Sgblack@eecs.umich.edu        packet->serialize(base + ".packet", os);
1847639Sgblack@eecs.umich.edu
1857639Sgblack@eecs.umich.edu    bool event_scheduled = doneEvent.scheduled();
1867639Sgblack@eecs.umich.edu    paramOut(os, base + ".event_scheduled", event_scheduled);
1877639Sgblack@eecs.umich.edu    if (event_scheduled) {
1887639Sgblack@eecs.umich.edu        Tick event_time = doneEvent.when();
1897639Sgblack@eecs.umich.edu        paramOut(os, base + ".event_time", event_time);
1907639Sgblack@eecs.umich.edu    }
1917639Sgblack@eecs.umich.edu
1927639Sgblack@eecs.umich.edu}
1937639Sgblack@eecs.umich.edu
1947639Sgblack@eecs.umich.eduvoid
1957639Sgblack@eecs.umich.eduEtherLink::Link::unserialize(const string &base, Checkpoint *cp,
1967639Sgblack@eecs.umich.edu                             const string &section)
1977639Sgblack@eecs.umich.edu{
1987639Sgblack@eecs.umich.edu    bool packet_exists;
1997639Sgblack@eecs.umich.edu    paramIn(cp, section, base + ".packet_exists", packet_exists);
2007639Sgblack@eecs.umich.edu    if (packet_exists) {
2017639Sgblack@eecs.umich.edu        packet = new EthPacketData(16384);
2027639Sgblack@eecs.umich.edu        packet->unserialize(base + ".packet", cp, section);
2037639Sgblack@eecs.umich.edu    }
2047639Sgblack@eecs.umich.edu
2057639Sgblack@eecs.umich.edu    bool event_scheduled;
2067639Sgblack@eecs.umich.edu    paramIn(cp, section, base + ".event_scheduled", event_scheduled);
2077639Sgblack@eecs.umich.edu    if (event_scheduled) {
2087639Sgblack@eecs.umich.edu        Tick event_time;
2097639Sgblack@eecs.umich.edu        paramIn(cp, section, base + ".event_time", event_time);
2107639Sgblack@eecs.umich.edu        doneEvent.schedule(event_time);
2117639Sgblack@eecs.umich.edu    }
21210037SARM gem5 Developers}
21310037SARM gem5 Developers
21410037SARM gem5 DevelopersLinkDelayEvent::LinkDelayEvent()
21510037SARM gem5 Developers    : Event(&mainEventQueue), link(NULL)
21610037SARM gem5 Developers{
21710037SARM gem5 Developers    setFlags(AutoSerialize);
21810037SARM gem5 Developers    setFlags(AutoDelete);
21910037SARM gem5 Developers}
22010037SARM gem5 Developers
22110037SARM gem5 DevelopersLinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, EthPacketPtr p, Tick when)
22210037SARM gem5 Developers    : Event(&mainEventQueue), link(l), packet(p)
22310037SARM gem5 Developers{
22410037SARM gem5 Developers    setFlags(AutoSerialize);
22510037SARM gem5 Developers    setFlags(AutoDelete);
22610037SARM gem5 Developers    schedule(when);
22710037SARM gem5 Developers}
22810037SARM gem5 Developers
22910037SARM gem5 Developersvoid
23010037SARM gem5 DevelopersLinkDelayEvent::process()
23110037SARM gem5 Developers{
23210037SARM gem5 Developers    link->txComplete(packet);
23310037SARM gem5 Developers}
23410037SARM gem5 Developers
23510037SARM gem5 Developersvoid
23610037SARM gem5 DevelopersLinkDelayEvent::serialize(ostream &os)
23710037SARM gem5 Developers{
23810037SARM gem5 Developers    paramOut(os, "type", string("LinkDelayEvent"));
23910037SARM gem5 Developers    Event::serialize(os);
24010037SARM gem5 Developers
24110037SARM gem5 Developers    EtherLink *parent = link->parent;
24210037SARM gem5 Developers    bool number = link->number;
24310037SARM gem5 Developers    SERIALIZE_OBJPTR(parent);
2447639Sgblack@eecs.umich.edu    SERIALIZE_SCALAR(number);
2457639Sgblack@eecs.umich.edu
2467639Sgblack@eecs.umich.edu    packet->serialize("packet", os);
2477639Sgblack@eecs.umich.edu}
2487639Sgblack@eecs.umich.edu
2497639Sgblack@eecs.umich.edu
2507639Sgblack@eecs.umich.eduvoid
2517639Sgblack@eecs.umich.eduLinkDelayEvent::unserialize(Checkpoint *cp, const string &section)
2527639Sgblack@eecs.umich.edu{
2537639Sgblack@eecs.umich.edu    Event::unserialize(cp, section);
2547639Sgblack@eecs.umich.edu
2557639Sgblack@eecs.umich.edu    EtherLink *parent;
2567639Sgblack@eecs.umich.edu    bool number;
2577639Sgblack@eecs.umich.edu    UNSERIALIZE_OBJPTR(parent);
2587639Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(number);
2597639Sgblack@eecs.umich.edu
2607639Sgblack@eecs.umich.edu    link = parent->link[number];
2617639Sgblack@eecs.umich.edu
2627639Sgblack@eecs.umich.edu    packet = new EthPacketData(16384);
2637639Sgblack@eecs.umich.edu    packet->unserialize("packet", cp, section);
2647639Sgblack@eecs.umich.edu}
2657639Sgblack@eecs.umich.edu
2667639Sgblack@eecs.umich.edu
2677639Sgblack@eecs.umich.eduSerializable *
2687639Sgblack@eecs.umich.eduLinkDelayEvent::createForUnserialize(Checkpoint *cp, const string &section)
2697639Sgblack@eecs.umich.edu{
2707639Sgblack@eecs.umich.edu    return new LinkDelayEvent();
2717639Sgblack@eecs.umich.edu}
2727639Sgblack@eecs.umich.edu
2737639Sgblack@eecs.umich.eduREGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent)
2747639Sgblack@eecs.umich.edu
2757639Sgblack@eecs.umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink)
2767639Sgblack@eecs.umich.edu
2777639Sgblack@eecs.umich.edu    SimObjectParam<EtherInt *> int1;
2787639Sgblack@eecs.umich.edu    SimObjectParam<EtherInt *> int2;
2797639Sgblack@eecs.umich.edu    Param<double> speed;
2807639Sgblack@eecs.umich.edu    Param<Tick> delay;
2817639Sgblack@eecs.umich.edu    Param<Tick> delay_var;
2827639Sgblack@eecs.umich.edu    SimObjectParam<EtherDump *> dump;
2837639Sgblack@eecs.umich.edu
2847639Sgblack@eecs.umich.eduEND_DECLARE_SIM_OBJECT_PARAMS(EtherLink)
2857639Sgblack@eecs.umich.edu
2867639Sgblack@eecs.umich.eduBEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink)
2877639Sgblack@eecs.umich.edu
2887639Sgblack@eecs.umich.edu    INIT_PARAM(int1, "interface 1"),
2897639Sgblack@eecs.umich.edu    INIT_PARAM(int2, "interface 2"),
2907639Sgblack@eecs.umich.edu    INIT_PARAM(speed, "link speed in bits per second"),
2917639Sgblack@eecs.umich.edu    INIT_PARAM(delay, "transmit delay of packets in us"),
2927639Sgblack@eecs.umich.edu    INIT_PARAM(delay_var, "Difference in amount of time to traverse wire"),
2937639Sgblack@eecs.umich.edu    INIT_PARAM(dump, "object to dump network packets to")
2947639Sgblack@eecs.umich.edu
2957639Sgblack@eecs.umich.eduEND_INIT_SIM_OBJECT_PARAMS(EtherLink)
2967639Sgblack@eecs.umich.edu
2977639Sgblack@eecs.umich.eduCREATE_SIM_OBJECT(EtherLink)
2987639Sgblack@eecs.umich.edu{
2997639Sgblack@eecs.umich.edu    return new EtherLink(getInstanceName(), int1, int2, speed, delay, delay_var,
3007639Sgblack@eecs.umich.edu                         dump);
3017639Sgblack@eecs.umich.edu}
3027639Sgblack@eecs.umich.edu
3037639Sgblack@eecs.umich.eduREGISTER_SIM_OBJECT("EtherLink", EtherLink)
3047639Sgblack@eecs.umich.edu