etherlink.cc revision 1762
11689SN/A/* 27944SGiacomo.Gabrielli@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 291689SN/A/* @file 301689SN/A * Device module for modelling a fixed bandwidth full duplex ethernet link 311689SN/A */ 321689SN/A 331689SN/A#include <cmath> 341689SN/A#include <deque> 351689SN/A#include <string> 361689SN/A#include <vector> 371689SN/A 381689SN/A#include "base/trace.hh" 392665Ssaidi@eecs.umich.edu#include "dev/etherdump.hh" 402665Ssaidi@eecs.umich.edu#include "dev/etherint.hh" 412831Sksewell@umich.edu#include "dev/etherlink.hh" 421689SN/A#include "dev/etherpkt.hh" 431689SN/A#include "sim/builder.hh" 442064SN/A#include "sim/serialize.hh" 451060SN/A#include "sim/system.hh" 461060SN/A#include "sim/root.hh" 472292SN/A 481717SN/Ausing namespace std; 494762Snate@binkert.org 506221Snate@binkert.orgEtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1, 514762Snate@binkert.org double rate, Tick delay, EtherDump *dump) 521060SN/A : SimObject(name) 536221Snate@binkert.org{ 545529Snate@binkert.org link[0] = new Link(name + ".link0", this, 0, rate, delay, dump); 551061SN/A link[1] = new Link(name + ".link1", this, 1, rate, delay, dump); 562292SN/A 575606Snate@binkert.org interface[0] = new Interface(name + ".int0", link[0], link[1]); 585606Snate@binkert.org interface[1] = new Interface(name + ".int1", link[1], link[0]); 595606Snate@binkert.org 601060SN/A interface[0]->setPeer(peer0); 612292SN/A peer0->setPeer(interface[0]); 622292SN/A interface[1]->setPeer(peer1); 632292SN/A peer1->setPeer(interface[1]); 642292SN/A} 652292SN/A 662292SN/AEtherLink::~EtherLink() 672292SN/A{ 682326SN/A delete link[0]; 692292SN/A delete link[1]; 702292SN/A 712292SN/A delete interface[0]; 722292SN/A delete interface[1]; 732292SN/A} 742292SN/A 755336Shines@cs.fsu.eduEtherLink::Interface::Interface(const string &name, Link *tx, Link *rx) 762292SN/A : EtherInt(name), txlink(tx) 774873Sstever@eecs.umich.edu{ 782292SN/A tx->setTxInt(this); 792292SN/A rx->setRxInt(this); 802292SN/A} 814329Sktlim@umich.edu 825529Snate@binkert.orgEtherLink::Link::Link(const string &name, EtherLink *p, int num, 834329Sktlim@umich.edu double rate, Tick delay, EtherDump *d) 844329Sktlim@umich.edu : objName(name), parent(p), number(num), txint(NULL), rxint(NULL), 854329Sktlim@umich.edu ticksPerByte(rate), linkDelay(delay), dump(d), 862292SN/A doneEvent(this) 872292SN/A{ } 882292SN/A 892292SN/Avoid 902292SN/AEtherLink::serialize(ostream &os) 912292SN/A{ 922292SN/A link[0]->serialize("link0", os); 932292SN/A link[1]->serialize("link1", os); 942307SN/A} 952307SN/A 965529Snate@binkert.orgvoid 971060SN/AEtherLink::unserialize(Checkpoint *cp, const string §ion) 981060SN/A{ 991060SN/A link[0]->unserialize("link0", cp, section); 1001060SN/A link[1]->unserialize("link1", cp, section); 1011060SN/A} 1021060SN/A 1032326SN/Avoid 1041060SN/AEtherLink::Link::txComplete(PacketPtr packet) 1051060SN/A{ 1061060SN/A DPRINTF(Ethernet, "packet received: len=%d\n", packet->length); 1071060SN/A DDUMP(EthernetData, packet->data, packet->length); 1082292SN/A rxint->sendPacket(packet); 1096221Snate@binkert.org} 1106221Snate@binkert.org 1116221Snate@binkert.orgclass LinkDelayEvent : public Event 1121060SN/A{ 1131060SN/A protected: 1142307SN/A EtherLink::Link *link; 1152292SN/A PacketPtr packet; 1162980Sgblack@eecs.umich.edu 1172292SN/A public: 1182292SN/A // non-scheduling version for createForUnserialize() 1192292SN/A LinkDelayEvent(); 1202292SN/A LinkDelayEvent(EtherLink::Link *link, PacketPtr pkt, Tick when); 1212292SN/A 1222292SN/A void process(); 1232292SN/A 1242292SN/A virtual void serialize(ostream &os); 1252292SN/A virtual void unserialize(Checkpoint *cp, const string §ion); 1262292SN/A static Serializable *createForUnserialize(Checkpoint *cp, 1276221Snate@binkert.org const string §ion); 1286221Snate@binkert.org}; 1292292SN/A 1302292SN/Avoid 1312292SN/AEtherLink::Link::txDone() 1322292SN/A{ 1332292SN/A if (dump) 1342292SN/A dump->dump(packet); 1352292SN/A 1362292SN/A if (linkDelay > 0) { 1372292SN/A DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay); 1386221Snate@binkert.org new LinkDelayEvent(this, packet, curTick + linkDelay); 1396221Snate@binkert.org } else { 1402292SN/A txComplete(packet); 1412292SN/A } 1422831Sksewell@umich.edu 1432292SN/A packet = 0; 1442292SN/A assert(!busy()); 1452292SN/A 1462292SN/A txint->sendDone(); 1472292SN/A} 1482292SN/A 1492292SN/Abool 1502292SN/AEtherLink::Link::transmit(PacketPtr pkt) 1512292SN/A{ 1526221Snate@binkert.org if (busy()) { 1536221Snate@binkert.org DPRINTF(Ethernet, "packet not sent, link busy\n"); 1542292SN/A return false; 1552292SN/A } 1562831Sksewell@umich.edu 1572292SN/A DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length); 1582292SN/A DDUMP(EthernetData, pkt->data, pkt->length); 1592292SN/A 1602292SN/A packet = pkt; 1612292SN/A Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0); 1622292SN/A DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", 1632292SN/A delay, ticksPerByte); 1642292SN/A doneEvent.schedule(curTick + delay); 1652292SN/A 1662292SN/A return true; 1672326SN/A} 1682348SN/A 1692326SN/Avoid 1702326SN/AEtherLink::Link::serialize(const string &base, ostream &os) 1712348SN/A{ 1722292SN/A bool packet_exists = packet; 1732292SN/A paramOut(os, base + ".packet_exists", packet_exists); 1742292SN/A if (packet_exists) 1752292SN/A packet->serialize(base + ".packet", os); 1762292SN/A 1772292SN/A bool event_scheduled = doneEvent.scheduled(); 1782292SN/A paramOut(os, base + ".event_scheduled", event_scheduled); 1791060SN/A if (event_scheduled) { 1801060SN/A Tick event_time = doneEvent.when(); 1811061SN/A paramOut(os, base + ".event_time", event_time); 1821060SN/A } 1831062SN/A 1841062SN/A} 1852301SN/A 1861062SN/Avoid 1871062SN/AEtherLink::Link::unserialize(const string &base, Checkpoint *cp, 1881062SN/A const string §ion) 1891062SN/A{ 1901062SN/A bool packet_exists; 1911062SN/A paramIn(cp, section, base + ".packet_exists", packet_exists); 1921062SN/A if (packet_exists) { 1931062SN/A packet = new PacketData(16384); 1941062SN/A packet->unserialize(base + ".packet", cp, section); 1951062SN/A } 1962301SN/A 1972301SN/A bool event_scheduled; 1982301SN/A paramIn(cp, section, base + ".event_scheduled", event_scheduled); 1992301SN/A if (event_scheduled) { 2001062SN/A Tick event_time; 2011062SN/A paramIn(cp, section, base + ".event_time", event_time); 2021062SN/A doneEvent.schedule(event_time); 2031062SN/A } 2041062SN/A} 2051062SN/A 2061062SN/ALinkDelayEvent::LinkDelayEvent() 2071062SN/A : Event(&mainEventQueue), link(NULL) 2081062SN/A{ 2091062SN/A setFlags(AutoSerialize); 2101062SN/A setFlags(AutoDelete); 2111062SN/A} 2121062SN/A 2131062SN/ALinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, PacketPtr p, Tick when) 2141062SN/A : Event(&mainEventQueue), link(l), packet(p) 2151062SN/A{ 2161062SN/A setFlags(AutoSerialize); 2171062SN/A setFlags(AutoDelete); 2181062SN/A schedule(when); 2191062SN/A} 2201062SN/A 2211062SN/Avoid 2221062SN/ALinkDelayEvent::process() 2231062SN/A{ 2241062SN/A link->txComplete(packet); 2251062SN/A} 2261062SN/A 2271062SN/Avoid 2281062SN/ALinkDelayEvent::serialize(ostream &os) 2291062SN/A{ 2301062SN/A paramOut(os, "type", string("LinkDelayEvent")); 2311062SN/A Event::serialize(os); 2321062SN/A 2331062SN/A EtherLink *parent = link->parent; 2341062SN/A bool number = link->number; 2351062SN/A SERIALIZE_OBJPTR(parent); 2361062SN/A SERIALIZE_SCALAR(number); 2371062SN/A 2381062SN/A packet->serialize("packet", os); 2391062SN/A} 2401062SN/A 2411062SN/A 2421062SN/Avoid 2431062SN/ALinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) 2441062SN/A{ 2451062SN/A Event::unserialize(cp, section); 2461062SN/A 2472361SN/A EtherLink *parent; 2482326SN/A bool number; 2492301SN/A UNSERIALIZE_OBJPTR(parent); 2502301SN/A UNSERIALIZE_SCALAR(number); 2512301SN/A 2522301SN/A link = parent->link[number]; 2532301SN/A 2542301SN/A packet = new PacketData(16384); 2552326SN/A packet->unserialize("packet", cp, section); 2562301SN/A} 2572361SN/A 2582326SN/A 2592307SN/ASerializable * 2602301SN/ALinkDelayEvent::createForUnserialize(Checkpoint *cp, const string §ion) 2612301SN/A{ 2622307SN/A return new LinkDelayEvent(); 2632301SN/A} 2642301SN/A 2652301SN/AREGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent) 2662301SN/A 2672301SN/ABEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 2682301SN/A 2692301SN/A SimObjectParam<EtherInt *> int1; 2702301SN/A SimObjectParam<EtherInt *> int2; 2712301SN/A Param<double> speed; 2722301SN/A Param<Tick> delay; 2732301SN/A SimObjectParam<EtherDump *> dump; 2742301SN/A 2752326SN/AEND_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 2764762Snate@binkert.org 2772301SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink) 2782301SN/A 2792301SN/A INIT_PARAM(int1, "interface 1"), 2802301SN/A INIT_PARAM(int2, "interface 2"), 2814762Snate@binkert.org INIT_PARAM(speed, "link speed in bits per second"), 2822301SN/A INIT_PARAM(delay, "transmit delay of packets in us"), 2832301SN/A INIT_PARAM(dump, "object to dump network packets to") 2842301SN/A 2852301SN/AEND_INIT_SIM_OBJECT_PARAMS(EtherLink) 2862361SN/A 2872326SN/ACREATE_SIM_OBJECT(EtherLink) 2882301SN/A{ 2892301SN/A return new EtherLink(getInstanceName(), int1, int2, speed, delay, dump); 2902301SN/A} 2912301SN/A 2922301SN/AREGISTER_SIM_OBJECT("EtherLink", EtherLink) 2932301SN/A