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 §ion) 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 §ion); 14612616Sgabeblack@google.com static Serializable *createForUnserialize(Checkpoint *cp, 1472124SN/A const string §ion); 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 §ion) 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 §ion) 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 §ion) 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