etherlink.cc revision 8229
11689SN/A/* 29444SAndreas.Sandberg@ARM.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 37944SGiacomo.Gabrielli@arm.com * All rights reserved. 47944SGiacomo.Gabrielli@arm.com * 57944SGiacomo.Gabrielli@arm.com * Redistribution and use in source and binary forms, with or without 67944SGiacomo.Gabrielli@arm.com * modification, are permitted provided that the following conditions are 77944SGiacomo.Gabrielli@arm.com * met: redistributions of source code must retain the above copyright 87944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer; 97944SGiacomo.Gabrielli@arm.com * redistributions in binary form must reproduce the above copyright 107944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer in the 117944SGiacomo.Gabrielli@arm.com * documentation and/or other materials provided with the distribution; 127944SGiacomo.Gabrielli@arm.com * neither the name of the copyright holders nor the names of its 137944SGiacomo.Gabrielli@arm.com * contributors may be used to endorse or promote products derived from 142326SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271689SN/A * 281689SN/A * Authors: Nathan Binkert 291689SN/A * Ron Dreslinski 301689SN/A */ 311689SN/A 321689SN/A/* @file 331689SN/A * Device module for modelling a fixed bandwidth full duplex ethernet link 341689SN/A */ 351689SN/A 361689SN/A#include <cmath> 371689SN/A#include <deque> 381689SN/A#include <string> 392665Ssaidi@eecs.umich.edu#include <vector> 402665Ssaidi@eecs.umich.edu 412831Sksewell@umich.edu#include "base/random.hh" 421689SN/A#include "base/trace.hh" 431689SN/A#include "dev/etherdump.hh" 442064SN/A#include "dev/etherint.hh" 451060SN/A#include "dev/etherlink.hh" 461060SN/A#include "dev/etherpkt.hh" 472292SN/A#include "params/EtherLink.hh" 481717SN/A#include "sim/core.hh" 498232Snate@binkert.org#include "sim/serialize.hh" 504762Snate@binkert.org#include "sim/system.hh" 516221Snate@binkert.org 524762Snate@binkert.orgusing namespace std; 531060SN/A 548737Skoansin.tan@gmail.comEtherLink::EtherLink(const Params *p) 558737Skoansin.tan@gmail.com : EtherObject(p) 568737Skoansin.tan@gmail.com{ 575529Snate@binkert.org link[0] = new Link(name() + ".link0", this, 0, p->speed, 581061SN/A p->delay, p->delay_var, p->dump); 592292SN/A link[1] = new Link(name() + ".link1", this, 1, p->speed, 605606Snate@binkert.org p->delay, p->delay_var, p->dump); 618581Ssteve.reinhardt@amd.com 628581Ssteve.reinhardt@amd.com interface[0] = new Interface(name() + ".int0", link[0], link[1]); 631060SN/A interface[1] = new Interface(name() + ".int1", link[1], link[0]); 642292SN/A} 652292SN/A 662292SN/A 672292SN/AEtherLink::~EtherLink() 682292SN/A{ 692292SN/A delete link[0]; 702326SN/A delete link[1]; 712292SN/A 722292SN/A delete interface[0]; 732292SN/A delete interface[1]; 742292SN/A} 752292SN/A 762292SN/AEtherInt* 775336Shines@cs.fsu.eduEtherLink::getEthPort(const std::string &if_name, int idx) 782292SN/A{ 794873Sstever@eecs.umich.edu Interface *i; 802292SN/A if (if_name == "int0") 812292SN/A i = interface[0]; 822292SN/A else if (if_name == "int1") 834329Sktlim@umich.edu i = interface[1]; 845529Snate@binkert.org else 854329Sktlim@umich.edu return NULL; 864329Sktlim@umich.edu if (i->getPeer()) 874329Sktlim@umich.edu panic("interface already connected to\n"); 882292SN/A 892292SN/A return i; 902292SN/A} 912292SN/A 922292SN/A 932292SN/AEtherLink::Interface::Interface(const string &name, Link *tx, Link *rx) 942292SN/A : EtherInt(name), txlink(tx) 952292SN/A{ 965529Snate@binkert.org tx->setTxInt(this); 971060SN/A rx->setRxInt(this); 981060SN/A} 991060SN/A 1001060SN/AEtherLink::Link::Link(const string &name, EtherLink *p, int num, 1011060SN/A double rate, Tick delay, Tick delay_var, EtherDump *d) 1021060SN/A : objName(name), parent(p), number(num), txint(NULL), rxint(NULL), 1032326SN/A ticksPerByte(rate), linkDelay(delay), delayVar(delay_var), dump(d), 1041060SN/A doneEvent(this) 1051060SN/A{ } 1061060SN/A 1071060SN/Avoid 1082292SN/AEtherLink::serialize(ostream &os) 1096221Snate@binkert.org{ 1106221Snate@binkert.org link[0]->serialize("link0", os); 1116221Snate@binkert.org link[1]->serialize("link1", os); 1121060SN/A} 1131060SN/A 1142307SN/Avoid 1152292SN/AEtherLink::unserialize(Checkpoint *cp, const string §ion) 1162980Sgblack@eecs.umich.edu{ 1172292SN/A link[0]->unserialize("link0", cp, section); 1182292SN/A link[1]->unserialize("link1", cp, section); 1192292SN/A} 1202292SN/A 1212292SN/Avoid 1222292SN/AEtherLink::Link::txComplete(EthPacketPtr packet) 1232292SN/A{ 1242292SN/A DPRINTF(Ethernet, "packet received: len=%d\n", packet->length); 1252292SN/A DDUMP(EthernetData, packet->data, packet->length); 1262292SN/A rxint->sendPacket(packet); 1276221Snate@binkert.org} 1286221Snate@binkert.org 1292292SN/Aclass LinkDelayEvent : public Event 1302292SN/A{ 1312292SN/A protected: 1322292SN/A EtherLink::Link *link; 1332292SN/A EthPacketPtr packet; 1342292SN/A 1352292SN/A public: 1362292SN/A // non-scheduling version for createForUnserialize() 1372292SN/A LinkDelayEvent(); 1386221Snate@binkert.org LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt); 1396221Snate@binkert.org 1402292SN/A void process(); 1412292SN/A 1422831Sksewell@umich.edu virtual void serialize(ostream &os); 1432292SN/A virtual void unserialize(Checkpoint *cp, const string §ion); 1442292SN/A static Serializable *createForUnserialize(Checkpoint *cp, 1452292SN/A const string §ion); 1462292SN/A}; 1472292SN/A 1482292SN/Avoid 1492292SN/AEtherLink::Link::txDone() 1502292SN/A{ 1512292SN/A if (dump) 1526221Snate@binkert.org dump->dump(packet); 1536221Snate@binkert.org 1542292SN/A if (linkDelay > 0) { 1552292SN/A DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay); 1562831Sksewell@umich.edu Event *event = new LinkDelayEvent(this, packet); 1572292SN/A parent->schedule(event, curTick() + linkDelay); 1582292SN/A } else { 1592292SN/A txComplete(packet); 1602292SN/A } 1612292SN/A 1622292SN/A packet = 0; 1632292SN/A assert(!busy()); 1642292SN/A 1652292SN/A txint->sendDone(); 1662292SN/A} 1672326SN/A 1682348SN/Abool 1692326SN/AEtherLink::Link::transmit(EthPacketPtr pkt) 1702326SN/A{ 1712348SN/A if (busy()) { 1722292SN/A DPRINTF(Ethernet, "packet not sent, link busy\n"); 1732292SN/A return false; 1742292SN/A } 1752292SN/A 1762292SN/A DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length); 1772292SN/A DDUMP(EthernetData, pkt->data, pkt->length); 1782292SN/A 1791060SN/A packet = pkt; 1801060SN/A Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0); 1811061SN/A if (delayVar != 0) 1821060SN/A delay += random_mt.random<Tick>(0, delayVar); 1831062SN/A 1841062SN/A DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", 1852301SN/A delay, ticksPerByte); 1861062SN/A parent->schedule(doneEvent, curTick() + delay); 1871062SN/A 1881062SN/A return true; 1891062SN/A} 1901062SN/A 1911062SN/Avoid 1921062SN/AEtherLink::Link::serialize(const string &base, ostream &os) 1931062SN/A{ 1941062SN/A bool packet_exists = packet; 1951062SN/A paramOut(os, base + ".packet_exists", packet_exists); 1962301SN/A if (packet_exists) 1972301SN/A packet->serialize(base + ".packet", os); 1982301SN/A 1992301SN/A bool event_scheduled = doneEvent.scheduled(); 2001062SN/A paramOut(os, base + ".event_scheduled", event_scheduled); 2011062SN/A if (event_scheduled) { 2021062SN/A Tick event_time = doneEvent.when(); 2031062SN/A paramOut(os, base + ".event_time", event_time); 2041062SN/A } 2051062SN/A 2061062SN/A} 2071062SN/A 2081062SN/Avoid 2091062SN/AEtherLink::Link::unserialize(const string &base, Checkpoint *cp, 2101062SN/A const string §ion) 2111062SN/A{ 2121062SN/A bool packet_exists; 2131062SN/A paramIn(cp, section, base + ".packet_exists", packet_exists); 2141062SN/A if (packet_exists) { 2151062SN/A packet = new EthPacketData(16384); 2161062SN/A packet->unserialize(base + ".packet", cp, section); 2171062SN/A } 2181062SN/A 2191062SN/A bool event_scheduled; 2201062SN/A paramIn(cp, section, base + ".event_scheduled", event_scheduled); 2211062SN/A if (event_scheduled) { 2221062SN/A Tick event_time; 2231062SN/A paramIn(cp, section, base + ".event_time", event_time); 2241062SN/A parent->schedule(doneEvent, event_time); 2251062SN/A } 2261062SN/A} 2271062SN/A 2281062SN/ALinkDelayEvent::LinkDelayEvent() 2291062SN/A : link(NULL) 2301062SN/A{ 2311062SN/A setFlags(AutoSerialize); 2321062SN/A setFlags(AutoDelete); 2331062SN/A} 2341062SN/A 2351062SN/ALinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, EthPacketPtr p) 2361062SN/A : link(l), packet(p) 2371062SN/A{ 2381062SN/A setFlags(AutoSerialize); 2391062SN/A setFlags(AutoDelete); 2401062SN/A} 2411062SN/A 2421062SN/Avoid 2431062SN/ALinkDelayEvent::process() 2441062SN/A{ 2451062SN/A link->txComplete(packet); 2461062SN/A} 2472361SN/A 2482326SN/Avoid 2492301SN/ALinkDelayEvent::serialize(ostream &os) 2502301SN/A{ 2512301SN/A paramOut(os, "type", string("LinkDelayEvent")); 2522301SN/A Event::serialize(os); 2532301SN/A 2542301SN/A EtherLink *parent = link->parent; 2552326SN/A bool number = link->number; 2562301SN/A SERIALIZE_OBJPTR(parent); 2572361SN/A SERIALIZE_SCALAR(number); 2582326SN/A 2592307SN/A packet->serialize("packet", os); 2608240Snate@binkert.org} 2612301SN/A 2622307SN/A 2632301SN/Avoid 2642301SN/ALinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) 2652301SN/A{ 2662301SN/A Event::unserialize(cp, section); 2678240Snate@binkert.org 2682301SN/A EtherLink *parent; 2692301SN/A bool number; 2702301SN/A UNSERIALIZE_OBJPTR(parent); 2712301SN/A UNSERIALIZE_SCALAR(number); 2722301SN/A 2732301SN/A link = parent->link[number]; 2742301SN/A 2752326SN/A packet = new EthPacketData(16384); 2764762Snate@binkert.org packet->unserialize("packet", cp, section); 2778240Snate@binkert.org} 2782301SN/A 2792301SN/A 2802301SN/ASerializable * 2814762Snate@binkert.orgLinkDelayEvent::createForUnserialize(Checkpoint *cp, const string §ion) 2822301SN/A{ 2832301SN/A return new LinkDelayEvent(); 2842301SN/A} 2852301SN/A 2862361SN/AREGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent) 2872326SN/A 2882301SN/AEtherLink * 2898240Snate@binkert.orgEtherLinkParams::create() 2902301SN/A{ 2912301SN/A return new EtherLink(this); 2922301SN/A} 2932301SN/A