etherlink.cc revision 1078
12686Sksewell@umich.edu/* 22100SN/A * Copyright (c) 2002-2004 The Regents of The University of Michigan 35222Sksewell@umich.edu * All rights reserved. 45222Sksewell@umich.edu * 55222Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 65222Sksewell@umich.edu * modification, are permitted provided that the following conditions are 75222Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 85222Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 95222Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 105222Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 115222Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 125222Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 135222Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 145222Sksewell@umich.edu * this software without specific prior written permission. 155222Sksewell@umich.edu * 165222Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175222Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185222Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195222Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205222Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215222Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225222Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235222Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245222Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255222Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265222Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275222Sksewell@umich.edu */ 285222Sksewell@umich.edu 295222Sksewell@umich.edu/* @file 305222Sksewell@umich.edu * Device module for modelling a fixed bandwidth full duplex ethernet link 315222Sksewell@umich.edu */ 325222Sksewell@umich.edu 335222Sksewell@umich.edu#include <cmath> 345222Sksewell@umich.edu#include <deque> 355222Sksewell@umich.edu#include <string> 365222Sksewell@umich.edu#include <vector> 375222Sksewell@umich.edu 382706Sksewell@umich.edu#include "base/trace.hh" 392022SN/A#include "dev/etherdump.hh" 402022SN/A#include "dev/etherint.hh" 412043SN/A#include "dev/etherlink.hh" 422024SN/A#include "dev/etherpkt.hh" 432024SN/A#include "sim/builder.hh" 442043SN/A#include "sim/serialize.hh" 452686Sksewell@umich.edu#include "sim/system.hh" 464661Sksewell@umich.edu#include "sim/universe.hh" 472022SN/A 482083SN/Ausing namespace std; 492686Sksewell@umich.edu 502101SN/AEtherLink::EtherLink(const string &name, EtherInt *i1, EtherInt *i2, 512043SN/A Tick speed, Tick dly, EtherDump *dump) 522043SN/A : SimObject(name) 532101SN/A{ 542101SN/A double rate = ((double)ticksPerSecond * 8.0) / (double)speed; 552686Sksewell@umich.edu Tick delay = US2Ticks(dly); 562686Sksewell@umich.edu 572101SN/A link1 = new Link(name + ".link1", rate, delay, dump); 582101SN/A link2 = new Link(name + ".link2", rate, delay, dump); 592101SN/A 602046SN/A int1 = new Interface(name + ".int1", link1, link2); 612686Sksewell@umich.edu int2 = new Interface(name + ".int2", link2, link1); 622686Sksewell@umich.edu 632686Sksewell@umich.edu int1->setPeer(i1); 642470SN/A i1->setPeer(int1); 652686Sksewell@umich.edu int2->setPeer(i2); 664661Sksewell@umich.edu i2->setPeer(int2); 675222Sksewell@umich.edu} 685222Sksewell@umich.edu 692686Sksewell@umich.eduEtherLink::~EtherLink() 702686Sksewell@umich.edu{ 712470SN/A delete link1; 722241SN/A delete link2; 732101SN/A 742495SN/A delete int1; 752495SN/A delete int2; 762495SN/A} 772101SN/A 782495SN/AEtherLink::Interface::Interface(const string &name, Link *tx, Link *rx) 792495SN/A : EtherInt(name), txlink(tx) 802495SN/A{ 812101SN/A tx->setTxInt(this); 822101SN/A rx->setRxInt(this); 832495SN/A} 842495SN/A 852495SN/AEtherLink::Link::Link(const string &name, double rate, Tick delay, 862495SN/A EtherDump *d) 872495SN/A : objName(name), txint(NULL), rxint(NULL), ticksPerByte(rate), 882495SN/A linkDelay(delay), dump(d), doneEvent(this) 892495SN/A{} 902495SN/A 912495SN/Avoid 922495SN/AEtherLink::serialize(ostream &os) 932495SN/A{ 942495SN/A nameOut(os, name() + ".link1"); 952495SN/A link1->serialize(os); 962101SN/A nameOut(os, name() + ".link2"); 972101SN/A link2->serialize(os); 982101SN/A} 992101SN/A 1002101SN/Avoid 1012101SN/AEtherLink::unserialize(Checkpoint *cp, const string §ion) 1022101SN/A{ 1032101SN/A link1->unserialize(cp, section + ".link1"); 1042101SN/A link2->unserialize(cp, section + ".link2"); 1052101SN/A} 1062495SN/A 1072495SN/Avoid 1082495SN/AEtherLink::Link::txComplete(PacketPtr &packet) 1092495SN/A{ 1102495SN/A DPRINTF(Ethernet, "packet received: len=%d\n", packet->length); 1112495SN/A DDUMP(EthernetData, packet->data, packet->length); 1122495SN/A rxint->sendPacket(packet); 1132495SN/A} 1142495SN/A 1152495SN/Aclass LinkDelayEvent : public Event 1162495SN/A{ 1172495SN/A protected: 1182495SN/A EtherLink::Link *link; 1192495SN/A PacketPtr packet; 1202495SN/A 1212043SN/A // non-scheduling version for createForUnserialize() 1222043SN/A LinkDelayEvent(EtherLink::Link *link); 1232025SN/A 1242043SN/A public: 1252686Sksewell@umich.edu LinkDelayEvent(EtherLink::Link *link, PacketPtr &pkt, Tick when); 1262686Sksewell@umich.edu 1272123SN/A void process(); 1282101SN/A 1295222Sksewell@umich.edu virtual void serialize(ostream &os); 1305222Sksewell@umich.edu virtual void unserialize(Checkpoint *cp, const string §ion); 1312101SN/A static Serializable *createForUnserialize(Checkpoint *cp, 1322042SN/A const string §ion); 1332101SN/A}; 1344661Sksewell@umich.edu 1352686Sksewell@umich.edu 1364661Sksewell@umich.eduvoid 1372101SN/AEtherLink::Link::txDone() 1382101SN/A{ 1392042SN/A if (dump) 1402101SN/A dump->dump(packet); 1412686Sksewell@umich.edu 1422686Sksewell@umich.edu if (linkDelay > 0) { 1435222Sksewell@umich.edu DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay); 1445222Sksewell@umich.edu new LinkDelayEvent(this, packet, curTick + linkDelay); 1455222Sksewell@umich.edu } else { 1465222Sksewell@umich.edu txComplete(packet); 1475222Sksewell@umich.edu } 1482965Sksewell@umich.edu 1495222Sksewell@umich.edu packet = 0; 1505222Sksewell@umich.edu assert(!busy()); 1512686Sksewell@umich.edu 1525222Sksewell@umich.edu txint->sendDone(); 1532101SN/A} 1542083SN/A 1552043SN/Abool 1562025SN/AEtherLink::Link::transmit(PacketPtr &pkt) 1572043SN/A{ 1585222Sksewell@umich.edu if (busy()) { 1594661Sksewell@umich.edu DPRINTF(Ethernet, "packet not sent, link busy\n"); 1605222Sksewell@umich.edu return false; 1614661Sksewell@umich.edu } 1622083SN/A 1632025SN/A DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length); 1642043SN/A DDUMP(EthernetData, pkt->data, pkt->length); 1654661Sksewell@umich.edu 1665222Sksewell@umich.edu packet = pkt; 1675222Sksewell@umich.edu Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0); 1684661Sksewell@umich.edu DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", 1694661Sksewell@umich.edu delay, ticksPerByte); 1702686Sksewell@umich.edu doneEvent.schedule(curTick + delay); 1714661Sksewell@umich.edu 1724661Sksewell@umich.edu return true; 1734661Sksewell@umich.edu} 1744661Sksewell@umich.edu 1755222Sksewell@umich.eduvoid 1765222Sksewell@umich.eduEtherLink::Link::serialize(ostream &os) 1774661Sksewell@umich.edu{ 1784661Sksewell@umich.edu bool packet_exists = packet; 1794661Sksewell@umich.edu SERIALIZE_SCALAR(packet_exists); 1804661Sksewell@umich.edu 1815222Sksewell@umich.edu bool event_scheduled = doneEvent.scheduled(); 1822101SN/A SERIALIZE_SCALAR(event_scheduled); 1832084SN/A if (event_scheduled) { 1842025SN/A Tick event_time = doneEvent.when(); 1852495SN/A SERIALIZE_SCALAR(event_time); 1862495SN/A } 1872495SN/A 1885222Sksewell@umich.edu if (packet_exists) { 1895222Sksewell@umich.edu nameOut(os, csprintf("%s.packet", name())); 1905222Sksewell@umich.edu packet->serialize(os); 1915222Sksewell@umich.edu } 1925222Sksewell@umich.edu} 1935222Sksewell@umich.edu 1945222Sksewell@umich.eduvoid 1955222Sksewell@umich.eduEtherLink::Link::unserialize(Checkpoint *cp, const string §ion) 1965222Sksewell@umich.edu{ 1975222Sksewell@umich.edu bool packet_exists; 1985222Sksewell@umich.edu UNSERIALIZE_SCALAR(packet_exists); 1995222Sksewell@umich.edu if (packet_exists) { 2005222Sksewell@umich.edu packet = new PacketData; 2015222Sksewell@umich.edu packet->unserialize(cp, csprintf("%s.packet", section)); 2025222Sksewell@umich.edu } 2035222Sksewell@umich.edu 2045222Sksewell@umich.edu bool event_scheduled; 2055222Sksewell@umich.edu UNSERIALIZE_SCALAR(event_scheduled); 2065222Sksewell@umich.edu if (event_scheduled) { 2075222Sksewell@umich.edu Tick event_time; 2082495SN/A UNSERIALIZE_SCALAR(event_time); 2095222Sksewell@umich.edu doneEvent.schedule(event_time); 2105222Sksewell@umich.edu } 2115222Sksewell@umich.edu} 2125222Sksewell@umich.edu 2135222Sksewell@umich.eduLinkDelayEvent::LinkDelayEvent(EtherLink::Link *l) 2145222Sksewell@umich.edu : Event(&mainEventQueue), link(l) 2155222Sksewell@umich.edu{ 2165222Sksewell@umich.edu setFlags(AutoSerialize); 2175222Sksewell@umich.edu setFlags(AutoDelete); 2185222Sksewell@umich.edu} 2195222Sksewell@umich.edu 2205222Sksewell@umich.eduLinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, PacketPtr &p, Tick when) 2215222Sksewell@umich.edu : Event(&mainEventQueue), link(l), packet(p) 2225222Sksewell@umich.edu{ 2235222Sksewell@umich.edu setFlags(AutoSerialize); 2242495SN/A setFlags(AutoDelete); 2252495SN/A schedule(when); 2262495SN/A} 2272495SN/A 2282495SN/Avoid 2292495SN/ALinkDelayEvent::process() 2302101SN/A{ 2312043SN/A link->txComplete(packet); 2322025SN/A} 2332495SN/A 2342495SN/Avoid 2352495SN/ALinkDelayEvent::serialize(ostream &os) 2362495SN/A{ 2372495SN/A paramOut(os, "type", string("LinkDelayEvent")); 2382495SN/A Event::serialize(os); 2392101SN/A SERIALIZE_OBJPTR(link); 2402084SN/A 2412024SN/A nameOut(os, csprintf("%s.packet", name())); 2422043SN/A packet->serialize(os); 2432239SN/A} 2442239SN/A 2452101SN/A 2462101SN/Avoid 2475222Sksewell@umich.eduLinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) 2482101SN/A{ 2492101SN/A Event::unserialize(cp, section); 2502101SN/A packet = new PacketData; 2512043SN/A packet->unserialize(cp, csprintf("%s.packet", section)); 2522043SN/A} 2532025SN/A 2542043SN/A 2552043SN/ASerializable * 2562101SN/ALinkDelayEvent::createForUnserialize(Checkpoint *cp, const string §ion) 2572101SN/A{ 2582101SN/A EtherLink::Link *link; 2592686Sksewell@umich.edu UNSERIALIZE_OBJPTR(link); 2602686Sksewell@umich.edu return new LinkDelayEvent(link); 2612101SN/A} 2622043SN/A 2632025SN/AREGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent) 2642043SN/A 2655222Sksewell@umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 2665222Sksewell@umich.edu 2675222Sksewell@umich.edu SimObjectParam<EtherInt *> interface1; 2685222Sksewell@umich.edu SimObjectParam<EtherInt *> interface2; 2695222Sksewell@umich.edu Param<Tick> link_speed; 2705222Sksewell@umich.edu Param<Tick> link_delay; 2715222Sksewell@umich.edu SimObjectParam<EtherDump *> packet_dump; 2722101SN/A 2732043SN/AEND_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 2742043SN/A 2752043SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink) 2762101SN/A 2772686Sksewell@umich.edu INIT_PARAM(interface1, "interface 1"), 2782686Sksewell@umich.edu INIT_PARAM(interface2, "interface 2"), 2792686Sksewell@umich.edu INIT_PARAM_DFLT(link_speed, "link speed in bits per second", 100000000), 2802686Sksewell@umich.edu INIT_PARAM_DFLT(link_delay, "transmit delay of packets in us", 0), 2812686Sksewell@umich.edu INIT_PARAM_DFLT(packet_dump, "object to dump network packets to", NULL) 2822686Sksewell@umich.edu 2832686Sksewell@umich.eduEND_INIT_SIM_OBJECT_PARAMS(EtherLink) 2842101SN/A 2852043SN/ACREATE_SIM_OBJECT(EtherLink) 2862043SN/A{ 2872043SN/A return new EtherLink(getInstanceName(), interface1, interface2, link_speed, 2884661Sksewell@umich.edu link_delay, packet_dump); 2894661Sksewell@umich.edu} 2902101SN/A 2912101SN/AREGISTER_SIM_OBJECT("EtherLink", EtherLink) 2922101SN/A