etherlink.cc revision 2665
17639Sgblack@eecs.umich.edu/* 27639Sgblack@eecs.umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan 310037SARM gem5 Developers * All rights reserved. 47639Sgblack@eecs.umich.edu * 57639Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67639Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77639Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87639Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97639Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107639Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117639Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127639Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137639Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 147639Sgblack@eecs.umich.edu * this software without specific prior written permission. 157639Sgblack@eecs.umich.edu * 167639Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177639Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187639Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197639Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207639Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217639Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227639Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237639Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247639Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257639Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267639Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277639Sgblack@eecs.umich.edu * 287639Sgblack@eecs.umich.edu * Authors: Nathan Binkert 297639Sgblack@eecs.umich.edu * Ron Dreslinski 307639Sgblack@eecs.umich.edu */ 317639Sgblack@eecs.umich.edu 327639Sgblack@eecs.umich.edu/* @file 337639Sgblack@eecs.umich.edu * Device module for modelling a fixed bandwidth full duplex ethernet link 347639Sgblack@eecs.umich.edu */ 357639Sgblack@eecs.umich.edu 367639Sgblack@eecs.umich.edu#include <cmath> 377639Sgblack@eecs.umich.edu#include <deque> 387639Sgblack@eecs.umich.edu#include <string> 397639Sgblack@eecs.umich.edu#include <vector> 407639Sgblack@eecs.umich.edu 417639Sgblack@eecs.umich.edu#include "base/random.hh" 427639Sgblack@eecs.umich.edu#include "base/trace.hh" 437639Sgblack@eecs.umich.edu#include "dev/etherdump.hh" 447639Sgblack@eecs.umich.edu#include "dev/etherint.hh" 457639Sgblack@eecs.umich.edu#include "dev/etherlink.hh" 467639Sgblack@eecs.umich.edu#include "dev/etherpkt.hh" 477639Sgblack@eecs.umich.edu#include "sim/builder.hh" 487639Sgblack@eecs.umich.edu#include "sim/serialize.hh" 497639Sgblack@eecs.umich.edu#include "sim/system.hh" 507639Sgblack@eecs.umich.edu#include "sim/root.hh" 517639Sgblack@eecs.umich.edu 527639Sgblack@eecs.umich.eduusing namespace std; 537639Sgblack@eecs.umich.edu 547639Sgblack@eecs.umich.eduEtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1, 557639Sgblack@eecs.umich.edu double rate, Tick delay, Tick delayVar, EtherDump *dump) 567639Sgblack@eecs.umich.edu : SimObject(name) 577639Sgblack@eecs.umich.edu{ 587639Sgblack@eecs.umich.edu link[0] = new Link(name + ".link0", this, 0, rate, delay, delayVar, dump); 597639Sgblack@eecs.umich.edu link[1] = new Link(name + ".link1", this, 1, rate, delay, delayVar, dump); 607639Sgblack@eecs.umich.edu 617639Sgblack@eecs.umich.edu interface[0] = new Interface(name + ".int0", link[0], link[1]); 627639Sgblack@eecs.umich.edu interface[1] = new Interface(name + ".int1", link[1], link[0]); 637639Sgblack@eecs.umich.edu 647639Sgblack@eecs.umich.edu interface[0]->setPeer(peer0); 657639Sgblack@eecs.umich.edu peer0->setPeer(interface[0]); 667639Sgblack@eecs.umich.edu interface[1]->setPeer(peer1); 677639Sgblack@eecs.umich.edu peer1->setPeer(interface[1]); 687639Sgblack@eecs.umich.edu} 697639Sgblack@eecs.umich.edu 707639Sgblack@eecs.umich.eduEtherLink::~EtherLink() 717639Sgblack@eecs.umich.edu{ 727639Sgblack@eecs.umich.edu delete link[0]; 737639Sgblack@eecs.umich.edu delete link[1]; 747639Sgblack@eecs.umich.edu 757639Sgblack@eecs.umich.edu delete interface[0]; 767639Sgblack@eecs.umich.edu delete interface[1]; 777639Sgblack@eecs.umich.edu} 787639Sgblack@eecs.umich.edu 797639Sgblack@eecs.umich.eduEtherLink::Interface::Interface(const string &name, Link *tx, Link *rx) 807639Sgblack@eecs.umich.edu : EtherInt(name), txlink(tx) 817639Sgblack@eecs.umich.edu{ 827639Sgblack@eecs.umich.edu tx->setTxInt(this); 837639Sgblack@eecs.umich.edu rx->setRxInt(this); 847639Sgblack@eecs.umich.edu} 857639Sgblack@eecs.umich.edu 867639Sgblack@eecs.umich.eduEtherLink::Link::Link(const string &name, EtherLink *p, int num, 877639Sgblack@eecs.umich.edu double rate, Tick delay, Tick delay_var, EtherDump *d) 887639Sgblack@eecs.umich.edu : objName(name), parent(p), number(num), txint(NULL), rxint(NULL), 897639Sgblack@eecs.umich.edu ticksPerByte(rate), linkDelay(delay), delayVar(delay_var), dump(d), 907639Sgblack@eecs.umich.edu doneEvent(this) 917639Sgblack@eecs.umich.edu{ } 927639Sgblack@eecs.umich.edu 937639Sgblack@eecs.umich.eduvoid 947639Sgblack@eecs.umich.eduEtherLink::serialize(ostream &os) 957639Sgblack@eecs.umich.edu{ 967639Sgblack@eecs.umich.edu link[0]->serialize("link0", os); 9710037SARM gem5 Developers link[1]->serialize("link1", os); 9810037SARM gem5 Developers} 997639Sgblack@eecs.umich.edu 1007639Sgblack@eecs.umich.eduvoid 1017639Sgblack@eecs.umich.eduEtherLink::unserialize(Checkpoint *cp, const string §ion) 1027639Sgblack@eecs.umich.edu{ 1037639Sgblack@eecs.umich.edu link[0]->unserialize("link0", cp, section); 1047639Sgblack@eecs.umich.edu link[1]->unserialize("link1", cp, section); 1057639Sgblack@eecs.umich.edu} 1067639Sgblack@eecs.umich.edu 1077639Sgblack@eecs.umich.eduvoid 1087639Sgblack@eecs.umich.eduEtherLink::Link::txComplete(EthPacketPtr packet) 1097639Sgblack@eecs.umich.edu{ 1107639Sgblack@eecs.umich.edu DPRINTF(Ethernet, "packet received: len=%d\n", packet->length); 1117639Sgblack@eecs.umich.edu DDUMP(EthernetData, packet->data, packet->length); 1127639Sgblack@eecs.umich.edu rxint->sendPacket(packet); 1137639Sgblack@eecs.umich.edu} 1147639Sgblack@eecs.umich.edu 11510037SARM gem5 Developersclass LinkDelayEvent : public Event 11610037SARM gem5 Developers{ 1177639Sgblack@eecs.umich.edu protected: 1187639Sgblack@eecs.umich.edu EtherLink::Link *link; 1197639Sgblack@eecs.umich.edu EthPacketPtr packet; 1207639Sgblack@eecs.umich.edu 1217639Sgblack@eecs.umich.edu public: 1227639Sgblack@eecs.umich.edu // non-scheduling version for createForUnserialize() 1237639Sgblack@eecs.umich.edu LinkDelayEvent(); 1247639Sgblack@eecs.umich.edu LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt, Tick when); 1257639Sgblack@eecs.umich.edu 1267639Sgblack@eecs.umich.edu void process(); 1277639Sgblack@eecs.umich.edu 1287639Sgblack@eecs.umich.edu virtual void serialize(ostream &os); 1297639Sgblack@eecs.umich.edu virtual void unserialize(Checkpoint *cp, const string §ion); 1307639Sgblack@eecs.umich.edu static Serializable *createForUnserialize(Checkpoint *cp, 1317639Sgblack@eecs.umich.edu const string §ion); 13210037SARM gem5 Developers}; 13310037SARM gem5 Developers 13410037SARM gem5 Developersvoid 13510037SARM gem5 DevelopersEtherLink::Link::txDone() 13610037SARM gem5 Developers{ 13710037SARM gem5 Developers if (dump) 13810037SARM gem5 Developers dump->dump(packet); 13910037SARM gem5 Developers 14010037SARM gem5 Developers if (linkDelay > 0) { 14110037SARM gem5 Developers DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay); 14210037SARM gem5 Developers new LinkDelayEvent(this, packet, curTick + linkDelay); 14310037SARM gem5 Developers } else { 14410037SARM gem5 Developers txComplete(packet); 14510037SARM gem5 Developers } 14610037SARM gem5 Developers 14710037SARM gem5 Developers packet = 0; 14810037SARM gem5 Developers assert(!busy()); 14910037SARM gem5 Developers 15010037SARM gem5 Developers txint->sendDone(); 15110037SARM gem5 Developers} 15210037SARM gem5 Developers 15310037SARM gem5 Developersbool 15410037SARM gem5 DevelopersEtherLink::Link::transmit(EthPacketPtr pkt) 15510037SARM gem5 Developers{ 15610037SARM gem5 Developers if (busy()) { 15710037SARM gem5 Developers DPRINTF(Ethernet, "packet not sent, link busy\n"); 15810037SARM gem5 Developers return false; 15910037SARM gem5 Developers } 16010037SARM gem5 Developers 16110037SARM gem5 Developers DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length); 16210037SARM gem5 Developers DDUMP(EthernetData, pkt->data, pkt->length); 16310037SARM gem5 Developers 1647639Sgblack@eecs.umich.edu packet = pkt; 1657639Sgblack@eecs.umich.edu Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0); 1667639Sgblack@eecs.umich.edu if (delayVar != 0) { 1677639Sgblack@eecs.umich.edu Random<Tick> var; 1687639Sgblack@eecs.umich.edu delay += var.uniform(0, delayVar); 1697639Sgblack@eecs.umich.edu } 1707639Sgblack@eecs.umich.edu DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", 1717639Sgblack@eecs.umich.edu delay, ticksPerByte); 1727639Sgblack@eecs.umich.edu doneEvent.schedule(curTick + delay); 1737639Sgblack@eecs.umich.edu 1747639Sgblack@eecs.umich.edu return true; 1757639Sgblack@eecs.umich.edu} 1767639Sgblack@eecs.umich.edu 1777639Sgblack@eecs.umich.eduvoid 1787639Sgblack@eecs.umich.eduEtherLink::Link::serialize(const string &base, ostream &os) 1797639Sgblack@eecs.umich.edu{ 1807639Sgblack@eecs.umich.edu bool packet_exists = packet; 1817639Sgblack@eecs.umich.edu paramOut(os, base + ".packet_exists", packet_exists); 1827639Sgblack@eecs.umich.edu if (packet_exists) 1837639Sgblack@eecs.umich.edu packet->serialize(base + ".packet", os); 1847639Sgblack@eecs.umich.edu 1857639Sgblack@eecs.umich.edu bool event_scheduled = doneEvent.scheduled(); 1867639Sgblack@eecs.umich.edu paramOut(os, base + ".event_scheduled", event_scheduled); 1877639Sgblack@eecs.umich.edu if (event_scheduled) { 1887639Sgblack@eecs.umich.edu Tick event_time = doneEvent.when(); 1897639Sgblack@eecs.umich.edu paramOut(os, base + ".event_time", event_time); 1907639Sgblack@eecs.umich.edu } 1917639Sgblack@eecs.umich.edu 1927639Sgblack@eecs.umich.edu} 1937639Sgblack@eecs.umich.edu 1947639Sgblack@eecs.umich.eduvoid 1957639Sgblack@eecs.umich.eduEtherLink::Link::unserialize(const string &base, Checkpoint *cp, 1967639Sgblack@eecs.umich.edu const string §ion) 1977639Sgblack@eecs.umich.edu{ 1987639Sgblack@eecs.umich.edu bool packet_exists; 1997639Sgblack@eecs.umich.edu paramIn(cp, section, base + ".packet_exists", packet_exists); 2007639Sgblack@eecs.umich.edu if (packet_exists) { 2017639Sgblack@eecs.umich.edu packet = new EthPacketData(16384); 2027639Sgblack@eecs.umich.edu packet->unserialize(base + ".packet", cp, section); 2037639Sgblack@eecs.umich.edu } 2047639Sgblack@eecs.umich.edu 2057639Sgblack@eecs.umich.edu bool event_scheduled; 2067639Sgblack@eecs.umich.edu paramIn(cp, section, base + ".event_scheduled", event_scheduled); 2077639Sgblack@eecs.umich.edu if (event_scheduled) { 2087639Sgblack@eecs.umich.edu Tick event_time; 2097639Sgblack@eecs.umich.edu paramIn(cp, section, base + ".event_time", event_time); 2107639Sgblack@eecs.umich.edu doneEvent.schedule(event_time); 2117639Sgblack@eecs.umich.edu } 21210037SARM gem5 Developers} 21310037SARM gem5 Developers 21410037SARM gem5 DevelopersLinkDelayEvent::LinkDelayEvent() 21510037SARM gem5 Developers : Event(&mainEventQueue), link(NULL) 21610037SARM gem5 Developers{ 21710037SARM gem5 Developers setFlags(AutoSerialize); 21810037SARM gem5 Developers setFlags(AutoDelete); 21910037SARM gem5 Developers} 22010037SARM gem5 Developers 22110037SARM gem5 DevelopersLinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, EthPacketPtr p, Tick when) 22210037SARM gem5 Developers : Event(&mainEventQueue), link(l), packet(p) 22310037SARM gem5 Developers{ 22410037SARM gem5 Developers setFlags(AutoSerialize); 22510037SARM gem5 Developers setFlags(AutoDelete); 22610037SARM gem5 Developers schedule(when); 22710037SARM gem5 Developers} 22810037SARM gem5 Developers 22910037SARM gem5 Developersvoid 23010037SARM gem5 DevelopersLinkDelayEvent::process() 23110037SARM gem5 Developers{ 23210037SARM gem5 Developers link->txComplete(packet); 23310037SARM gem5 Developers} 23410037SARM gem5 Developers 23510037SARM gem5 Developersvoid 23610037SARM gem5 DevelopersLinkDelayEvent::serialize(ostream &os) 23710037SARM gem5 Developers{ 23810037SARM gem5 Developers paramOut(os, "type", string("LinkDelayEvent")); 23910037SARM gem5 Developers Event::serialize(os); 24010037SARM gem5 Developers 24110037SARM gem5 Developers EtherLink *parent = link->parent; 24210037SARM gem5 Developers bool number = link->number; 24310037SARM gem5 Developers SERIALIZE_OBJPTR(parent); 2447639Sgblack@eecs.umich.edu SERIALIZE_SCALAR(number); 2457639Sgblack@eecs.umich.edu 2467639Sgblack@eecs.umich.edu packet->serialize("packet", os); 2477639Sgblack@eecs.umich.edu} 2487639Sgblack@eecs.umich.edu 2497639Sgblack@eecs.umich.edu 2507639Sgblack@eecs.umich.eduvoid 2517639Sgblack@eecs.umich.eduLinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) 2527639Sgblack@eecs.umich.edu{ 2537639Sgblack@eecs.umich.edu Event::unserialize(cp, section); 2547639Sgblack@eecs.umich.edu 2557639Sgblack@eecs.umich.edu EtherLink *parent; 2567639Sgblack@eecs.umich.edu bool number; 2577639Sgblack@eecs.umich.edu UNSERIALIZE_OBJPTR(parent); 2587639Sgblack@eecs.umich.edu UNSERIALIZE_SCALAR(number); 2597639Sgblack@eecs.umich.edu 2607639Sgblack@eecs.umich.edu link = parent->link[number]; 2617639Sgblack@eecs.umich.edu 2627639Sgblack@eecs.umich.edu packet = new EthPacketData(16384); 2637639Sgblack@eecs.umich.edu packet->unserialize("packet", cp, section); 2647639Sgblack@eecs.umich.edu} 2657639Sgblack@eecs.umich.edu 2667639Sgblack@eecs.umich.edu 2677639Sgblack@eecs.umich.eduSerializable * 2687639Sgblack@eecs.umich.eduLinkDelayEvent::createForUnserialize(Checkpoint *cp, const string §ion) 2697639Sgblack@eecs.umich.edu{ 2707639Sgblack@eecs.umich.edu return new LinkDelayEvent(); 2717639Sgblack@eecs.umich.edu} 2727639Sgblack@eecs.umich.edu 2737639Sgblack@eecs.umich.eduREGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent) 2747639Sgblack@eecs.umich.edu 2757639Sgblack@eecs.umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 2767639Sgblack@eecs.umich.edu 2777639Sgblack@eecs.umich.edu SimObjectParam<EtherInt *> int1; 2787639Sgblack@eecs.umich.edu SimObjectParam<EtherInt *> int2; 2797639Sgblack@eecs.umich.edu Param<double> speed; 2807639Sgblack@eecs.umich.edu Param<Tick> delay; 2817639Sgblack@eecs.umich.edu Param<Tick> delay_var; 2827639Sgblack@eecs.umich.edu SimObjectParam<EtherDump *> dump; 2837639Sgblack@eecs.umich.edu 2847639Sgblack@eecs.umich.eduEND_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 2857639Sgblack@eecs.umich.edu 2867639Sgblack@eecs.umich.eduBEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink) 2877639Sgblack@eecs.umich.edu 2887639Sgblack@eecs.umich.edu INIT_PARAM(int1, "interface 1"), 2897639Sgblack@eecs.umich.edu INIT_PARAM(int2, "interface 2"), 2907639Sgblack@eecs.umich.edu INIT_PARAM(speed, "link speed in bits per second"), 2917639Sgblack@eecs.umich.edu INIT_PARAM(delay, "transmit delay of packets in us"), 2927639Sgblack@eecs.umich.edu INIT_PARAM(delay_var, "Difference in amount of time to traverse wire"), 2937639Sgblack@eecs.umich.edu INIT_PARAM(dump, "object to dump network packets to") 2947639Sgblack@eecs.umich.edu 2957639Sgblack@eecs.umich.eduEND_INIT_SIM_OBJECT_PARAMS(EtherLink) 2967639Sgblack@eecs.umich.edu 2977639Sgblack@eecs.umich.eduCREATE_SIM_OBJECT(EtherLink) 2987639Sgblack@eecs.umich.edu{ 2997639Sgblack@eecs.umich.edu return new EtherLink(getInstanceName(), int1, int2, speed, delay, delay_var, 3007639Sgblack@eecs.umich.edu dump); 3017639Sgblack@eecs.umich.edu} 3027639Sgblack@eecs.umich.edu 3037639Sgblack@eecs.umich.eduREGISTER_SIM_OBJECT("EtherLink", EtherLink) 3047639Sgblack@eecs.umich.edu