etherlink.cc revision 1435
12315SN/A/*
28733Sgeoffrey.blake@arm.com * Copyright (c) 2002-2004 The Regents of The University of Michigan
38733Sgeoffrey.blake@arm.com * All rights reserved.
48733Sgeoffrey.blake@arm.com *
58733Sgeoffrey.blake@arm.com * Redistribution and use in source and binary forms, with or without
68733Sgeoffrey.blake@arm.com * modification, are permitted provided that the following conditions are
78733Sgeoffrey.blake@arm.com * met: redistributions of source code must retain the above copyright
88733Sgeoffrey.blake@arm.com * notice, this list of conditions and the following disclaimer;
98733Sgeoffrey.blake@arm.com * redistributions in binary form must reproduce the above copyright
108733Sgeoffrey.blake@arm.com * notice, this list of conditions and the following disclaimer in the
118733Sgeoffrey.blake@arm.com * documentation and/or other materials provided with the distribution;
128733Sgeoffrey.blake@arm.com * neither the name of the copyright holders nor the names of its
138733Sgeoffrey.blake@arm.com * contributors may be used to endorse or promote products derived from
142332SN/A * this software without specific prior written permission.
152315SN/A *
162315SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172315SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182315SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192315SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202315SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212315SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222315SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232315SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242315SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252315SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262315SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272315SN/A */
282315SN/A
292315SN/A/* @file
302315SN/A * Device module for modelling a fixed bandwidth full duplex ethernet link
312315SN/A */
322315SN/A
332315SN/A#include <cmath>
342315SN/A#include <deque>
352315SN/A#include <string>
362315SN/A#include <vector>
372315SN/A
382315SN/A#include "base/trace.hh"
392689Sktlim@umich.edu#include "dev/etherdump.hh"
402689Sktlim@umich.edu#include "dev/etherint.hh"
412315SN/A#include "dev/etherlink.hh"
422315SN/A#include "dev/etherpkt.hh"
432315SN/A#include "sim/builder.hh"
442315SN/A#include "sim/serialize.hh"
452315SN/A#include "sim/system.hh"
462315SN/A#include "sim/universe.hh"
478229Snate@binkert.org
482315SN/Ausing namespace std;
492315SN/A
502669Sktlim@umich.eduEtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1,
512315SN/A                     Tick speed, Tick dly, EtherDump *dump)
522315SN/A    : SimObject(name)
532315SN/A{
548229Snate@binkert.org    double rate = ((double)ticksPerSecond * 8.0) / (double)speed;
552683Sktlim@umich.edu    Tick delay = US2Ticks(dly);
562315SN/A
578733Sgeoffrey.blake@arm.com    link[0] = new Link(name + ".link0", this, 0, rate, delay, dump);
588733Sgeoffrey.blake@arm.com    link[1] = new Link(name + ".link1", this, 1, rate, delay, dump);
592315SN/A
602315SN/A    interface[0] = new Interface(name + ".int0", link[0], link[1]);
612315SN/A    interface[1] = new Interface(name + ".int1", link[1], link[0]);
623468Sgblack@eecs.umich.edu
633468Sgblack@eecs.umich.edu    interface[0]->setPeer(peer0);
646022Sgblack@eecs.umich.edu    peer0->setPeer(interface[0]);
653468Sgblack@eecs.umich.edu    interface[1]->setPeer(peer1);
662315SN/A    peer1->setPeer(interface[1]);
672315SN/A}
682315SN/A
692680Sktlim@umich.eduEtherLink::~EtherLink()
702669Sktlim@umich.edu{
712315SN/A    delete link[0];
722350SN/A    delete link[1];
732350SN/A
742350SN/A    delete interface[0];
752350SN/A    delete interface[1];
762350SN/A}
772350SN/A
782350SN/AEtherLink::Interface::Interface(const string &name, Link *tx, Link *rx)
792350SN/A    : EtherInt(name), txlink(tx)
802350SN/A{
812350SN/A    tx->setTxInt(this);
822680Sktlim@umich.edu    rx->setRxInt(this);
832683Sktlim@umich.edu}
842680Sktlim@umich.edu
852350SN/AEtherLink::Link::Link(const string &name, EtherLink *p, int num,
862680Sktlim@umich.edu                      double rate, Tick delay, EtherDump *d)
872350SN/A    : objName(name), parent(p), number(num), txint(NULL), rxint(NULL),
882315SN/A      ticksPerByte(rate), linkDelay(delay), dump(d),
892315SN/A      doneEvent(this)
902315SN/A{ }
912315SN/A
922669Sktlim@umich.eduvoid
932669Sktlim@umich.eduEtherLink::serialize(ostream &os)
942315SN/A{
958832SAli.Saidi@ARM.com    link[0]->serialize("link0", os);
968832SAli.Saidi@ARM.com    link[1]->serialize("link1", os);
978832SAli.Saidi@ARM.com}
982315SN/A
992315SN/Avoid
1002315SN/AEtherLink::unserialize(Checkpoint *cp, const string &section)
1015529Snate@binkert.org{
1022315SN/A    link[0]->unserialize("link0", cp, section);
1032315SN/A    link[1]->unserialize("link1", cp, section);
1042315SN/A}
1052315SN/A
1062315SN/Avoid
1079608Sandreas.hansson@arm.comEtherLink::Link::txComplete(PacketPtr packet)
1082679Sktlim@umich.edu{
1099608Sandreas.hansson@arm.com    DPRINTF(Ethernet, "packet received: len=%d\n", packet->length);
1102679Sktlim@umich.edu    DDUMP(EthernetData, packet->data, packet->length);
1119608Sandreas.hansson@arm.com    rxint->sendPacket(packet);
1128887Sgeoffrey.blake@arm.com}
1139176Sandreas.hansson@arm.com
1149176Sandreas.hansson@arm.comclass LinkDelayEvent : public Event
1159176Sandreas.hansson@arm.com{
1168887Sgeoffrey.blake@arm.com  protected:
1178887Sgeoffrey.blake@arm.com    EtherLink::Link *link;
1188887Sgeoffrey.blake@arm.com    PacketPtr packet;
1199608Sandreas.hansson@arm.com
1208887Sgeoffrey.blake@arm.com  public:
1219176Sandreas.hansson@arm.com    // non-scheduling version for createForUnserialize()
1229176Sandreas.hansson@arm.com    LinkDelayEvent();
1239176Sandreas.hansson@arm.com    LinkDelayEvent(EtherLink::Link *link, PacketPtr pkt, Tick when);
1248887Sgeoffrey.blake@arm.com
1258887Sgeoffrey.blake@arm.com    void process();
1262679Sktlim@umich.edu
1279176Sandreas.hansson@arm.com    virtual void serialize(ostream &os);
1289176Sandreas.hansson@arm.com    virtual void unserialize(Checkpoint *cp, const string &section);
1299176Sandreas.hansson@arm.com    static Serializable *createForUnserialize(Checkpoint *cp,
1309176Sandreas.hansson@arm.com                                              const string &section);
1319176Sandreas.hansson@arm.com};
1329176Sandreas.hansson@arm.com
1339608Sandreas.hansson@arm.comvoid
1349608Sandreas.hansson@arm.comEtherLink::Link::txDone()
1352315SN/A{
1362680Sktlim@umich.edu    if (dump)
1372315SN/A        dump->dump(packet);
1386022Sgblack@eecs.umich.edu
1396022Sgblack@eecs.umich.edu    if (linkDelay > 0) {
1402315SN/A        DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay);
1412315SN/A        new LinkDelayEvent(this, packet, curTick + linkDelay);
1422315SN/A    } else {
1432315SN/A        txComplete(packet);
1442315SN/A    }
1452315SN/A
1468733Sgeoffrey.blake@arm.com    packet = 0;
1478733Sgeoffrey.blake@arm.com    assert(!busy());
1488733Sgeoffrey.blake@arm.com
1498733Sgeoffrey.blake@arm.com    txint->sendDone();
1502315SN/A}
1512315SN/A
1528733Sgeoffrey.blake@arm.combool
1538733Sgeoffrey.blake@arm.comEtherLink::Link::transmit(PacketPtr pkt)
1548733Sgeoffrey.blake@arm.com{
1552315SN/A    if (busy()) {
1562679Sktlim@umich.edu        DPRINTF(Ethernet, "packet not sent, link busy\n");
1572679Sktlim@umich.edu        return false;
1582315SN/A    }
1592315SN/A
1608733Sgeoffrey.blake@arm.com    DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length);
1612315SN/A    DDUMP(EthernetData, pkt->data, pkt->length);
1622315SN/A
1632315SN/A    packet = pkt;
1642315SN/A    Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0);
1652315SN/A    DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
1662315SN/A            delay, ticksPerByte);
1672315SN/A    doneEvent.schedule(curTick + delay);
1689176Sandreas.hansson@arm.com
1699176Sandreas.hansson@arm.com    return true;
1709176Sandreas.hansson@arm.com}
1719176Sandreas.hansson@arm.com
1729176Sandreas.hansson@arm.comvoid
1738733Sgeoffrey.blake@arm.comEtherLink::Link::serialize(const string &base, ostream &os)
1748733Sgeoffrey.blake@arm.com{
1758733Sgeoffrey.blake@arm.com    bool packet_exists = packet;
1768887Sgeoffrey.blake@arm.com    paramOut(os, base + ".packet_exists", packet_exists);
1778887Sgeoffrey.blake@arm.com    if (packet_exists)
1788887Sgeoffrey.blake@arm.com        packet->serialize(base + ".packet", os);
1798887Sgeoffrey.blake@arm.com
1808887Sgeoffrey.blake@arm.com    bool event_scheduled = doneEvent.scheduled();
1818887Sgeoffrey.blake@arm.com    paramOut(os, base + ".event_scheuled", event_scheduled);
1822315SN/A    if (event_scheduled) {
1832930Sktlim@umich.edu        Tick event_time = doneEvent.when();
1842315SN/A        paramOut(os, base + ".event_time", event_time);
1852315SN/A    }
1862315SN/A
1872315SN/A}
1882315SN/A
1892315SN/Avoid
1902315SN/AEtherLink::Link::unserialize(const string &base, Checkpoint *cp,
1912315SN/A                             const string &section)
1922315SN/A{
1932315SN/A    bool packet_exists;
1942315SN/A    paramIn(cp, section, base + ".packet_exists", packet_exists);
1952315SN/A    if (packet_exists) {
1965543Ssaidi@eecs.umich.edu        packet = new PacketData(16384);
1972315SN/A        packet->unserialize(base + ".packet", cp, section);
1982315SN/A    }
1992315SN/A
2002315SN/A    bool event_scheduled;
2012315SN/A    paramIn(cp, section, base + ".event_scheduled", event_scheduled);
2022315SN/A    if (event_scheduled) {
2032315SN/A        Tick event_time;
2042315SN/A        paramIn(cp, section, base + ".event_time", event_time);
2052315SN/A        doneEvent.schedule(event_time);
2062315SN/A    }
2072315SN/A}
2082315SN/A
2093735Sstever@eecs.umich.eduLinkDelayEvent::LinkDelayEvent()
2102315SN/A    : Event(&mainEventQueue), link(NULL)
2112683Sktlim@umich.edu{
2122315SN/A    setFlags(AutoSerialize);
2132315SN/A    setFlags(AutoDelete);
2143735Sstever@eecs.umich.edu}
2152315SN/A
2169918Ssteve.reinhardt@amd.comLinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, PacketPtr p, Tick when)
2172683Sktlim@umich.edu    : Event(&mainEventQueue), link(l), packet(p)
2182315SN/A{
2192315SN/A    setFlags(AutoSerialize);
2203735Sstever@eecs.umich.edu    setFlags(AutoDelete);
2212669Sktlim@umich.edu    schedule(when);
2229918Ssteve.reinhardt@amd.com}
2232683Sktlim@umich.edu
2242315SN/Avoid
2252315SN/ALinkDelayEvent::process()
2268733Sgeoffrey.blake@arm.com{
2278733Sgeoffrey.blake@arm.com    link->txComplete(packet);
2288733Sgeoffrey.blake@arm.com}
2298733Sgeoffrey.blake@arm.com
2308733Sgeoffrey.blake@arm.comvoid
2318733Sgeoffrey.blake@arm.comLinkDelayEvent::serialize(ostream &os)
2328733Sgeoffrey.blake@arm.com{
2338733Sgeoffrey.blake@arm.com    paramOut(os, "type", string("LinkDelayEvent"));
2343735Sstever@eecs.umich.edu    Event::serialize(os);
2352315SN/A
2362683Sktlim@umich.edu    EtherLink *parent = link->parent;
2378733Sgeoffrey.blake@arm.com    bool number = link->number;
2382315SN/A    SERIALIZE_OBJPTR(parent);
2392315SN/A    SERIALIZE_SCALAR(number);
2403735Sstever@eecs.umich.edu
2412669Sktlim@umich.edu    packet->serialize("packet", os);
2429918Ssteve.reinhardt@amd.com}
2432683Sktlim@umich.edu
2448733Sgeoffrey.blake@arm.com
2452315SN/Avoid
2462315SN/ALinkDelayEvent::unserialize(Checkpoint *cp, const string &section)
2473735Sstever@eecs.umich.edu{
2483735Sstever@eecs.umich.edu    Event::unserialize(cp, section);
2492315SN/A
2509918Ssteve.reinhardt@amd.com    EtherLink *parent;
2512683Sktlim@umich.edu    bool number;
2528733Sgeoffrey.blake@arm.com    UNSERIALIZE_OBJPTR(parent);
2532315SN/A    UNSERIALIZE_SCALAR(number);
2542315SN/A
2558733Sgeoffrey.blake@arm.com    link = parent->link[number];
2568733Sgeoffrey.blake@arm.com
2578733Sgeoffrey.blake@arm.com    packet = new PacketData(16384);
2588733Sgeoffrey.blake@arm.com    packet->unserialize("packet", cp, section);
2598733Sgeoffrey.blake@arm.com}
2602669Sktlim@umich.edu
2618733Sgeoffrey.blake@arm.com
2628733Sgeoffrey.blake@arm.comSerializable *
2638733Sgeoffrey.blake@arm.comLinkDelayEvent::createForUnserialize(Checkpoint *cp, const string &section)
2648733Sgeoffrey.blake@arm.com{
2658733Sgeoffrey.blake@arm.com    return new LinkDelayEvent();
2668733Sgeoffrey.blake@arm.com}
2678733Sgeoffrey.blake@arm.com
2688733Sgeoffrey.blake@arm.comREGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent)
2698733Sgeoffrey.blake@arm.com
2708733Sgeoffrey.blake@arm.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink)
2718733Sgeoffrey.blake@arm.com
2722315SN/A    SimObjectParam<EtherInt *> int1;
2734172Ssaidi@eecs.umich.edu    SimObjectParam<EtherInt *> int2;
2744172Ssaidi@eecs.umich.edu    Param<Tick> speed;
2754172Ssaidi@eecs.umich.edu    Param<Tick> delay;
2764172Ssaidi@eecs.umich.edu    SimObjectParam<EtherDump *> dump;
2774172Ssaidi@eecs.umich.edu
2782315SN/AEND_DECLARE_SIM_OBJECT_PARAMS(EtherLink)
2792315SN/A
2802683Sktlim@umich.eduBEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink)
2812315SN/A
2822315SN/A    INIT_PARAM(int1, "interface 1"),
2834172Ssaidi@eecs.umich.edu    INIT_PARAM(int2, "interface 2"),
2842315SN/A    INIT_PARAM_DFLT(speed, "link speed in bits per second", 100000000),
2854172Ssaidi@eecs.umich.edu    INIT_PARAM_DFLT(delay, "transmit delay of packets in us", 0),
2864172Ssaidi@eecs.umich.edu    INIT_PARAM_DFLT(dump, "object to dump network packets to", NULL)
2872315SN/A
2882315SN/AEND_INIT_SIM_OBJECT_PARAMS(EtherLink)
2893468Sgblack@eecs.umich.edu
2902315SN/ACREATE_SIM_OBJECT(EtherLink)
2912315SN/A{
2922683Sktlim@umich.edu    return new EtherLink(getInstanceName(), int1, int2, speed, delay, dump);
2932315SN/A}
2942315SN/A
2958733Sgeoffrey.blake@arm.comREGISTER_SIM_OBJECT("EtherLink", EtherLink)
2968733Sgeoffrey.blake@arm.com