etherlink.cc revision 8232
12124SN/A/*
22124SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
35268Sksewell@umich.edu * All rights reserved.
45268Sksewell@umich.edu *
55268Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
65268Sksewell@umich.edu * modification, are permitted provided that the following conditions are
75268Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
85268Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
95268Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
105268Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
115268Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
125268Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
135268Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
145268Sksewell@umich.edu * this software without specific prior written permission.
155268Sksewell@umich.edu *
165268Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175268Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185268Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195268Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205268Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215268Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225268Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235268Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245268Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255268Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265268Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275268Sksewell@umich.edu *
285268Sksewell@umich.edu * Authors: Nathan Binkert
295268Sksewell@umich.edu *          Ron Dreslinski
305268Sksewell@umich.edu */
312022SN/A
322649Ssaidi@eecs.umich.edu/* @file
332649Ssaidi@eecs.umich.edu * Device module for modelling a fixed bandwidth full duplex ethernet link
342706Sksewell@umich.edu */
352649Ssaidi@eecs.umich.edu
362649Ssaidi@eecs.umich.edu#include <cmath>
372022SN/A#include <deque>
382124SN/A#include <string>
392124SN/A#include <vector>
402124SN/A
412124SN/A#include "base/random.hh"
422124SN/A#include "base/trace.hh"
432124SN/A#include "debug/Ethernet.hh"
442124SN/A#include "debug/EthernetData.hh"
455736Snate@binkert.org#include "dev/etherdump.hh"
462239SN/A#include "dev/etherint.hh"
472124SN/A#include "dev/etherlink.hh"
482124SN/A#include "dev/etherpkt.hh"
492124SN/A#include "params/EtherLink.hh"
502124SN/A#include "sim/core.hh"
516207Sksewell@umich.edu#include "sim/serialize.hh"
522124SN/A#include "sim/system.hh"
532742Sksewell@umich.edu
542022SN/Ausing namespace std;
552124SN/A
562022SN/AEtherLink::EtherLink(const Params *p)
5712616Sgabeblack@google.com    : EtherObject(p)
5812616Sgabeblack@google.com{
592124SN/A    link[0] = new Link(name() + ".link0", this, 0, p->speed,
602124SN/A                       p->delay, p->delay_var, p->dump);
612742Sksewell@umich.edu    link[1] = new Link(name() + ".link1", this, 1, p->speed,
622742Sksewell@umich.edu                       p->delay, p->delay_var, p->dump);
632742Sksewell@umich.edu
642742Sksewell@umich.edu    interface[0] = new Interface(name() + ".int0", link[0], link[1]);
652742Sksewell@umich.edu    interface[1] = new Interface(name() + ".int1", link[1], link[0]);
662742Sksewell@umich.edu}
672742Sksewell@umich.edu
682742Sksewell@umich.edu
696207Sksewell@umich.eduEtherLink::~EtherLink()
706207Sksewell@umich.edu{
712742Sksewell@umich.edu    delete link[0];
722742Sksewell@umich.edu    delete link[1];
732742Sksewell@umich.edu
7412616Sgabeblack@google.com    delete interface[0];
7512616Sgabeblack@google.com    delete interface[1];
762742Sksewell@umich.edu}
772022SN/A
782022SN/AEtherInt*
792124SN/AEtherLink::getEthPort(const std::string &if_name, int idx)
802022SN/A{
812124SN/A    Interface *i;
822124SN/A    if (if_name == "int0")
832124SN/A        i = interface[0];
842742Sksewell@umich.edu    else if (if_name == "int1")
852239SN/A        i = interface[1];
862124SN/A    else
872124SN/A        return NULL;
882742Sksewell@umich.edu    if (i->getPeer())
892742Sksewell@umich.edu        panic("interface already connected to\n");
902742Sksewell@umich.edu
912742Sksewell@umich.edu    return i;
922742Sksewell@umich.edu}
932742Sksewell@umich.edu
942742Sksewell@umich.edu
952742Sksewell@umich.eduEtherLink::Interface::Interface(const string &name, Link *tx, Link *rx)
964661Sksewell@umich.edu    : EtherInt(name), txlink(tx)
974661Sksewell@umich.edu{
984661Sksewell@umich.edu    tx->setTxInt(this);
999554Sandreas.hansson@arm.com    rx->setRxInt(this);
10012234Sgabeblack@google.com}
1019554Sandreas.hansson@arm.com
1029554Sandreas.hansson@arm.comEtherLink::Link::Link(const string &name, EtherLink *p, int num,
1039554Sandreas.hansson@arm.com                      double rate, Tick delay, Tick delay_var, EtherDump *d)
1044661Sksewell@umich.edu    : objName(name), parent(p), number(num), txint(NULL), rxint(NULL),
1054661Sksewell@umich.edu      ticksPerByte(rate), linkDelay(delay), delayVar(delay_var), dump(d),
1064661Sksewell@umich.edu      doneEvent(this)
1074661Sksewell@umich.edu{ }
10812234Sgabeblack@google.com
1094661Sksewell@umich.eduvoid
1104661Sksewell@umich.eduEtherLink::serialize(ostream &os)
1115222Sksewell@umich.edu{
11213233Sgabeblack@google.com    link[0]->serialize("link0", os);
1134661Sksewell@umich.edu    link[1]->serialize("link1", os);
1145222Sksewell@umich.edu}
11513233Sgabeblack@google.com
1164661Sksewell@umich.eduvoid
1175222Sksewell@umich.eduEtherLink::unserialize(Checkpoint *cp, const string &section)
11813233Sgabeblack@google.com{
1194661Sksewell@umich.edu    link[0]->unserialize("link0", cp, section);
1205222Sksewell@umich.edu    link[1]->unserialize("link1", cp, section);
12113233Sgabeblack@google.com}
1224661Sksewell@umich.edu
1234661Sksewell@umich.eduvoid
12413449Sgabeblack@google.comEtherLink::Link::txComplete(EthPacketPtr packet)
1254661Sksewell@umich.edu{
1264661Sksewell@umich.edu    DPRINTF(Ethernet, "packet received: len=%d\n", packet->length);
1274661Sksewell@umich.edu    DDUMP(EthernetData, packet->data, packet->length);
1284661Sksewell@umich.edu    rxint->sendPacket(packet);
1294661Sksewell@umich.edu}
1302022SN/A
1312022SN/Aclass LinkDelayEvent : public Event
1322124SN/A{
1332124SN/A  protected:
1342124SN/A    EtherLink::Link *link;
1352124SN/A    EthPacketPtr packet;
1362124SN/A
1372124SN/A  public:
1382124SN/A    // non-scheduling version for createForUnserialize()
1392124SN/A    LinkDelayEvent();
1402124SN/A    LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt);
1414661Sksewell@umich.edu
1422124SN/A    void process();
14312616Sgabeblack@google.com
14412616Sgabeblack@google.com    virtual void serialize(ostream &os);
14512616Sgabeblack@google.com    virtual void unserialize(Checkpoint *cp, const string &section);
14612616Sgabeblack@google.com    static Serializable *createForUnserialize(Checkpoint *cp,
1472124SN/A                                              const string &section);
1482022SN/A};
1492022SN/A
1502124SN/Avoid
1516207Sksewell@umich.eduEtherLink::Link::txDone()
15210184SCurtis.Dunham@arm.com{
1536207Sksewell@umich.edu    if (dump)
1542124SN/A        dump->dump(packet);
1553953Sstever@eecs.umich.edu
1562124SN/A    if (linkDelay > 0) {
1573953Sstever@eecs.umich.edu        DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay);
1582124SN/A        Event *event = new LinkDelayEvent(this, packet);
1592124SN/A        parent->schedule(event, curTick() + linkDelay);
16012234Sgabeblack@google.com    } else {
1612124SN/A        txComplete(packet);
1622124SN/A    }
1632124SN/A
1642132SN/A    packet = 0;
1652124SN/A    assert(!busy());
1665222Sksewell@umich.edu
1675222Sksewell@umich.edu    txint->sendDone();
1685222Sksewell@umich.edu}
1695222Sksewell@umich.edu
1705222Sksewell@umich.edubool
1715222Sksewell@umich.eduEtherLink::Link::transmit(EthPacketPtr pkt)
1725222Sksewell@umich.edu{
1732124SN/A    if (busy()) {
1742124SN/A        DPRINTF(Ethernet, "packet not sent, link busy\n");
1752124SN/A        return false;
1762124SN/A    }
1772124SN/A
1788442Sgblack@eecs.umich.edu    DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length);
1792124SN/A    DDUMP(EthernetData, pkt->data, pkt->length);
1802124SN/A
1812124SN/A    packet = pkt;
1822124SN/A    Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0);
1832124SN/A    if (delayVar != 0)
1842124SN/A        delay += random_mt.random<Tick>(0, delayVar);
1852124SN/A
1862124SN/A    DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
1872124SN/A            delay, ticksPerByte);
1882124SN/A    parent->schedule(doneEvent, curTick() + delay);
1892124SN/A
1902124SN/A    return true;
1912124SN/A}
19212234Sgabeblack@google.com
1932124SN/Avoid
1942124SN/AEtherLink::Link::serialize(const string &base, ostream &os)
1952239SN/A{
1962132SN/A    bool packet_exists = packet;
1972239SN/A    paramOut(os, base + ".packet_exists", packet_exists);
1985222Sksewell@umich.edu    if (packet_exists)
1995222Sksewell@umich.edu        packet->serialize(base + ".packet", os);
2005222Sksewell@umich.edu
2015222Sksewell@umich.edu    bool event_scheduled = doneEvent.scheduled();
2025222Sksewell@umich.edu    paramOut(os, base + ".event_scheduled", event_scheduled);
2035222Sksewell@umich.edu    if (event_scheduled) {
2045222Sksewell@umich.edu        Tick event_time = doneEvent.when();
2052239SN/A        paramOut(os, base + ".event_time", event_time);
2062239SN/A    }
2072239SN/A
2082239SN/A}
2092239SN/A
21011303Ssteve.reinhardt@amd.comvoid
2112239SN/AEtherLink::Link::unserialize(const string &base, Checkpoint *cp,
2122239SN/A                             const string &section)
2132124SN/A{
2142124SN/A    bool packet_exists;
2152124SN/A    paramIn(cp, section, base + ".packet_exists", packet_exists);
2162124SN/A    if (packet_exists) {
2172124SN/A        packet = new EthPacketData(16384);
21812234Sgabeblack@google.com        packet->unserialize(base + ".packet", cp, section);
2192124SN/A    }
2202124SN/A
2212132SN/A    bool event_scheduled;
2222239SN/A    paramIn(cp, section, base + ".event_scheduled", event_scheduled);
2235222Sksewell@umich.edu    if (event_scheduled) {
2245222Sksewell@umich.edu        Tick event_time;
2255222Sksewell@umich.edu        paramIn(cp, section, base + ".event_time", event_time);
2265222Sksewell@umich.edu        parent->schedule(doneEvent, event_time);
2275222Sksewell@umich.edu    }
2285222Sksewell@umich.edu}
2295222Sksewell@umich.edu
2302506SN/ALinkDelayEvent::LinkDelayEvent()
2314661Sksewell@umich.edu    : link(NULL)
2322239SN/A{
2338442Sgblack@eecs.umich.edu    setFlags(AutoSerialize);
2342239SN/A    setFlags(AutoDelete);
2352239SN/A}
2362239SN/A
2372239SN/ALinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, EthPacketPtr p)
2382239SN/A    : link(l), packet(p)
2392239SN/A{
2402239SN/A    setFlags(AutoSerialize);
2412239SN/A    setFlags(AutoDelete);
2422239SN/A}
2432124SN/A
2442124SN/Avoid
2452124SN/ALinkDelayEvent::process()
2462124SN/A{
2472124SN/A    link->txComplete(packet);
24812234Sgabeblack@google.com}
2492124SN/A
2502124SN/Avoid
2512124SN/ALinkDelayEvent::serialize(ostream &os)
2522132SN/A{
2534056Sstever@eecs.umich.edu    paramOut(os, "type", string("LinkDelayEvent"));
2544056Sstever@eecs.umich.edu    Event::serialize(os);
2554056Sstever@eecs.umich.edu
2564056Sstever@eecs.umich.edu    EtherLink *parent = link->parent;
2574056Sstever@eecs.umich.edu    bool number = link->number;
2584056Sstever@eecs.umich.edu    SERIALIZE_OBJPTR(parent);
2594056Sstever@eecs.umich.edu    SERIALIZE_SCALAR(number);
2604056Sstever@eecs.umich.edu
2614056Sstever@eecs.umich.edu    packet->serialize("packet", os);
2624056Sstever@eecs.umich.edu}
2634056Sstever@eecs.umich.edu
2648442Sgblack@eecs.umich.edu
2658442Sgblack@eecs.umich.eduvoid
2664056Sstever@eecs.umich.eduLinkDelayEvent::unserialize(Checkpoint *cp, const string &section)
2674056Sstever@eecs.umich.edu{
2684056Sstever@eecs.umich.edu    Event::unserialize(cp, section);
2694056Sstever@eecs.umich.edu
2704056Sstever@eecs.umich.edu    EtherLink *parent;
2714056Sstever@eecs.umich.edu    bool number;
2724056Sstever@eecs.umich.edu    UNSERIALIZE_OBJPTR(parent);
2734056Sstever@eecs.umich.edu    UNSERIALIZE_SCALAR(number);
2744056Sstever@eecs.umich.edu
2754056Sstever@eecs.umich.edu    link = parent->link[number];
2764056Sstever@eecs.umich.edu
2774056Sstever@eecs.umich.edu    packet = new EthPacketData(16384);
2784056Sstever@eecs.umich.edu    packet->unserialize("packet", cp, section);
2794056Sstever@eecs.umich.edu}
2805222Sksewell@umich.edu
2815222Sksewell@umich.edu
28212234Sgabeblack@google.comSerializable *
2835222Sksewell@umich.eduLinkDelayEvent::createForUnserialize(Checkpoint *cp, const string &section)
2845222Sksewell@umich.edu{
2855222Sksewell@umich.edu    return new LinkDelayEvent();
2865222Sksewell@umich.edu}
2875222Sksewell@umich.edu
2885222Sksewell@umich.eduREGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent)
2895222Sksewell@umich.edu
2905222Sksewell@umich.eduEtherLink *
2915222Sksewell@umich.eduEtherLinkParams::create()
2925222Sksewell@umich.edu{
2935222Sksewell@umich.edu    return new EtherLink(this);
2945222Sksewell@umich.edu}
2955222Sksewell@umich.edu