etherlink.cc revision 1435
12315SN/A/* 28733Sgeoffrey.blake@arm.com * Copyright (c) 2002-2004 The Regents of The University of Michigan 38733Sgeoffrey.blake@arm.com * All rights reserved. 48733Sgeoffrey.blake@arm.com * 58733Sgeoffrey.blake@arm.com * Redistribution and use in source and binary forms, with or without 68733Sgeoffrey.blake@arm.com * modification, are permitted provided that the following conditions are 78733Sgeoffrey.blake@arm.com * met: redistributions of source code must retain the above copyright 88733Sgeoffrey.blake@arm.com * notice, this list of conditions and the following disclaimer; 98733Sgeoffrey.blake@arm.com * redistributions in binary form must reproduce the above copyright 108733Sgeoffrey.blake@arm.com * notice, this list of conditions and the following disclaimer in the 118733Sgeoffrey.blake@arm.com * documentation and/or other materials provided with the distribution; 128733Sgeoffrey.blake@arm.com * neither the name of the copyright holders nor the names of its 138733Sgeoffrey.blake@arm.com * contributors may be used to endorse or promote products derived from 142332SN/A * this software without specific prior written permission. 152315SN/A * 162315SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172315SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182315SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192315SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202315SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212315SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222315SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232315SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242315SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252315SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262315SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272315SN/A */ 282315SN/A 292315SN/A/* @file 302315SN/A * Device module for modelling a fixed bandwidth full duplex ethernet link 312315SN/A */ 322315SN/A 332315SN/A#include <cmath> 342315SN/A#include <deque> 352315SN/A#include <string> 362315SN/A#include <vector> 372315SN/A 382315SN/A#include "base/trace.hh" 392689Sktlim@umich.edu#include "dev/etherdump.hh" 402689Sktlim@umich.edu#include "dev/etherint.hh" 412315SN/A#include "dev/etherlink.hh" 422315SN/A#include "dev/etherpkt.hh" 432315SN/A#include "sim/builder.hh" 442315SN/A#include "sim/serialize.hh" 452315SN/A#include "sim/system.hh" 462315SN/A#include "sim/universe.hh" 478229Snate@binkert.org 482315SN/Ausing namespace std; 492315SN/A 502669Sktlim@umich.eduEtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1, 512315SN/A Tick speed, Tick dly, EtherDump *dump) 522315SN/A : SimObject(name) 532315SN/A{ 548229Snate@binkert.org double rate = ((double)ticksPerSecond * 8.0) / (double)speed; 552683Sktlim@umich.edu Tick delay = US2Ticks(dly); 562315SN/A 578733Sgeoffrey.blake@arm.com link[0] = new Link(name + ".link0", this, 0, rate, delay, dump); 588733Sgeoffrey.blake@arm.com link[1] = new Link(name + ".link1", this, 1, rate, delay, dump); 592315SN/A 602315SN/A interface[0] = new Interface(name + ".int0", link[0], link[1]); 612315SN/A interface[1] = new Interface(name + ".int1", link[1], link[0]); 623468Sgblack@eecs.umich.edu 633468Sgblack@eecs.umich.edu interface[0]->setPeer(peer0); 646022Sgblack@eecs.umich.edu peer0->setPeer(interface[0]); 653468Sgblack@eecs.umich.edu interface[1]->setPeer(peer1); 662315SN/A peer1->setPeer(interface[1]); 672315SN/A} 682315SN/A 692680Sktlim@umich.eduEtherLink::~EtherLink() 702669Sktlim@umich.edu{ 712315SN/A delete link[0]; 722350SN/A delete link[1]; 732350SN/A 742350SN/A delete interface[0]; 752350SN/A delete interface[1]; 762350SN/A} 772350SN/A 782350SN/AEtherLink::Interface::Interface(const string &name, Link *tx, Link *rx) 792350SN/A : EtherInt(name), txlink(tx) 802350SN/A{ 812350SN/A tx->setTxInt(this); 822680Sktlim@umich.edu rx->setRxInt(this); 832683Sktlim@umich.edu} 842680Sktlim@umich.edu 852350SN/AEtherLink::Link::Link(const string &name, EtherLink *p, int num, 862680Sktlim@umich.edu double rate, Tick delay, EtherDump *d) 872350SN/A : objName(name), parent(p), number(num), txint(NULL), rxint(NULL), 882315SN/A ticksPerByte(rate), linkDelay(delay), dump(d), 892315SN/A doneEvent(this) 902315SN/A{ } 912315SN/A 922669Sktlim@umich.eduvoid 932669Sktlim@umich.eduEtherLink::serialize(ostream &os) 942315SN/A{ 958832SAli.Saidi@ARM.com link[0]->serialize("link0", os); 968832SAli.Saidi@ARM.com link[1]->serialize("link1", os); 978832SAli.Saidi@ARM.com} 982315SN/A 992315SN/Avoid 1002315SN/AEtherLink::unserialize(Checkpoint *cp, const string §ion) 1015529Snate@binkert.org{ 1022315SN/A link[0]->unserialize("link0", cp, section); 1032315SN/A link[1]->unserialize("link1", cp, section); 1042315SN/A} 1052315SN/A 1062315SN/Avoid 1079608Sandreas.hansson@arm.comEtherLink::Link::txComplete(PacketPtr packet) 1082679Sktlim@umich.edu{ 1099608Sandreas.hansson@arm.com DPRINTF(Ethernet, "packet received: len=%d\n", packet->length); 1102679Sktlim@umich.edu DDUMP(EthernetData, packet->data, packet->length); 1119608Sandreas.hansson@arm.com rxint->sendPacket(packet); 1128887Sgeoffrey.blake@arm.com} 1139176Sandreas.hansson@arm.com 1149176Sandreas.hansson@arm.comclass LinkDelayEvent : public Event 1159176Sandreas.hansson@arm.com{ 1168887Sgeoffrey.blake@arm.com protected: 1178887Sgeoffrey.blake@arm.com EtherLink::Link *link; 1188887Sgeoffrey.blake@arm.com PacketPtr packet; 1199608Sandreas.hansson@arm.com 1208887Sgeoffrey.blake@arm.com public: 1219176Sandreas.hansson@arm.com // non-scheduling version for createForUnserialize() 1229176Sandreas.hansson@arm.com LinkDelayEvent(); 1239176Sandreas.hansson@arm.com LinkDelayEvent(EtherLink::Link *link, PacketPtr pkt, Tick when); 1248887Sgeoffrey.blake@arm.com 1258887Sgeoffrey.blake@arm.com void process(); 1262679Sktlim@umich.edu 1279176Sandreas.hansson@arm.com virtual void serialize(ostream &os); 1289176Sandreas.hansson@arm.com virtual void unserialize(Checkpoint *cp, const string §ion); 1299176Sandreas.hansson@arm.com static Serializable *createForUnserialize(Checkpoint *cp, 1309176Sandreas.hansson@arm.com const string §ion); 1319176Sandreas.hansson@arm.com}; 1329176Sandreas.hansson@arm.com 1339608Sandreas.hansson@arm.comvoid 1349608Sandreas.hansson@arm.comEtherLink::Link::txDone() 1352315SN/A{ 1362680Sktlim@umich.edu if (dump) 1372315SN/A dump->dump(packet); 1386022Sgblack@eecs.umich.edu 1396022Sgblack@eecs.umich.edu if (linkDelay > 0) { 1402315SN/A DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay); 1412315SN/A new LinkDelayEvent(this, packet, curTick + linkDelay); 1422315SN/A } else { 1432315SN/A txComplete(packet); 1442315SN/A } 1452315SN/A 1468733Sgeoffrey.blake@arm.com packet = 0; 1478733Sgeoffrey.blake@arm.com assert(!busy()); 1488733Sgeoffrey.blake@arm.com 1498733Sgeoffrey.blake@arm.com txint->sendDone(); 1502315SN/A} 1512315SN/A 1528733Sgeoffrey.blake@arm.combool 1538733Sgeoffrey.blake@arm.comEtherLink::Link::transmit(PacketPtr pkt) 1548733Sgeoffrey.blake@arm.com{ 1552315SN/A if (busy()) { 1562679Sktlim@umich.edu DPRINTF(Ethernet, "packet not sent, link busy\n"); 1572679Sktlim@umich.edu return false; 1582315SN/A } 1592315SN/A 1608733Sgeoffrey.blake@arm.com DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length); 1612315SN/A DDUMP(EthernetData, pkt->data, pkt->length); 1622315SN/A 1632315SN/A packet = pkt; 1642315SN/A Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0); 1652315SN/A DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", 1662315SN/A delay, ticksPerByte); 1672315SN/A doneEvent.schedule(curTick + delay); 1689176Sandreas.hansson@arm.com 1699176Sandreas.hansson@arm.com return true; 1709176Sandreas.hansson@arm.com} 1719176Sandreas.hansson@arm.com 1729176Sandreas.hansson@arm.comvoid 1738733Sgeoffrey.blake@arm.comEtherLink::Link::serialize(const string &base, ostream &os) 1748733Sgeoffrey.blake@arm.com{ 1758733Sgeoffrey.blake@arm.com bool packet_exists = packet; 1768887Sgeoffrey.blake@arm.com paramOut(os, base + ".packet_exists", packet_exists); 1778887Sgeoffrey.blake@arm.com if (packet_exists) 1788887Sgeoffrey.blake@arm.com packet->serialize(base + ".packet", os); 1798887Sgeoffrey.blake@arm.com 1808887Sgeoffrey.blake@arm.com bool event_scheduled = doneEvent.scheduled(); 1818887Sgeoffrey.blake@arm.com paramOut(os, base + ".event_scheuled", event_scheduled); 1822315SN/A if (event_scheduled) { 1832930Sktlim@umich.edu Tick event_time = doneEvent.when(); 1842315SN/A paramOut(os, base + ".event_time", event_time); 1852315SN/A } 1862315SN/A 1872315SN/A} 1882315SN/A 1892315SN/Avoid 1902315SN/AEtherLink::Link::unserialize(const string &base, Checkpoint *cp, 1912315SN/A const string §ion) 1922315SN/A{ 1932315SN/A bool packet_exists; 1942315SN/A paramIn(cp, section, base + ".packet_exists", packet_exists); 1952315SN/A if (packet_exists) { 1965543Ssaidi@eecs.umich.edu packet = new PacketData(16384); 1972315SN/A packet->unserialize(base + ".packet", cp, section); 1982315SN/A } 1992315SN/A 2002315SN/A bool event_scheduled; 2012315SN/A paramIn(cp, section, base + ".event_scheduled", event_scheduled); 2022315SN/A if (event_scheduled) { 2032315SN/A Tick event_time; 2042315SN/A paramIn(cp, section, base + ".event_time", event_time); 2052315SN/A doneEvent.schedule(event_time); 2062315SN/A } 2072315SN/A} 2082315SN/A 2093735Sstever@eecs.umich.eduLinkDelayEvent::LinkDelayEvent() 2102315SN/A : Event(&mainEventQueue), link(NULL) 2112683Sktlim@umich.edu{ 2122315SN/A setFlags(AutoSerialize); 2132315SN/A setFlags(AutoDelete); 2143735Sstever@eecs.umich.edu} 2152315SN/A 2169918Ssteve.reinhardt@amd.comLinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, PacketPtr p, Tick when) 2172683Sktlim@umich.edu : Event(&mainEventQueue), link(l), packet(p) 2182315SN/A{ 2192315SN/A setFlags(AutoSerialize); 2203735Sstever@eecs.umich.edu setFlags(AutoDelete); 2212669Sktlim@umich.edu schedule(when); 2229918Ssteve.reinhardt@amd.com} 2232683Sktlim@umich.edu 2242315SN/Avoid 2252315SN/ALinkDelayEvent::process() 2268733Sgeoffrey.blake@arm.com{ 2278733Sgeoffrey.blake@arm.com link->txComplete(packet); 2288733Sgeoffrey.blake@arm.com} 2298733Sgeoffrey.blake@arm.com 2308733Sgeoffrey.blake@arm.comvoid 2318733Sgeoffrey.blake@arm.comLinkDelayEvent::serialize(ostream &os) 2328733Sgeoffrey.blake@arm.com{ 2338733Sgeoffrey.blake@arm.com paramOut(os, "type", string("LinkDelayEvent")); 2343735Sstever@eecs.umich.edu Event::serialize(os); 2352315SN/A 2362683Sktlim@umich.edu EtherLink *parent = link->parent; 2378733Sgeoffrey.blake@arm.com bool number = link->number; 2382315SN/A SERIALIZE_OBJPTR(parent); 2392315SN/A SERIALIZE_SCALAR(number); 2403735Sstever@eecs.umich.edu 2412669Sktlim@umich.edu packet->serialize("packet", os); 2429918Ssteve.reinhardt@amd.com} 2432683Sktlim@umich.edu 2448733Sgeoffrey.blake@arm.com 2452315SN/Avoid 2462315SN/ALinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) 2473735Sstever@eecs.umich.edu{ 2483735Sstever@eecs.umich.edu Event::unserialize(cp, section); 2492315SN/A 2509918Ssteve.reinhardt@amd.com EtherLink *parent; 2512683Sktlim@umich.edu bool number; 2528733Sgeoffrey.blake@arm.com UNSERIALIZE_OBJPTR(parent); 2532315SN/A UNSERIALIZE_SCALAR(number); 2542315SN/A 2558733Sgeoffrey.blake@arm.com link = parent->link[number]; 2568733Sgeoffrey.blake@arm.com 2578733Sgeoffrey.blake@arm.com packet = new PacketData(16384); 2588733Sgeoffrey.blake@arm.com packet->unserialize("packet", cp, section); 2598733Sgeoffrey.blake@arm.com} 2602669Sktlim@umich.edu 2618733Sgeoffrey.blake@arm.com 2628733Sgeoffrey.blake@arm.comSerializable * 2638733Sgeoffrey.blake@arm.comLinkDelayEvent::createForUnserialize(Checkpoint *cp, const string §ion) 2648733Sgeoffrey.blake@arm.com{ 2658733Sgeoffrey.blake@arm.com return new LinkDelayEvent(); 2668733Sgeoffrey.blake@arm.com} 2678733Sgeoffrey.blake@arm.com 2688733Sgeoffrey.blake@arm.comREGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent) 2698733Sgeoffrey.blake@arm.com 2708733Sgeoffrey.blake@arm.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 2718733Sgeoffrey.blake@arm.com 2722315SN/A SimObjectParam<EtherInt *> int1; 2734172Ssaidi@eecs.umich.edu SimObjectParam<EtherInt *> int2; 2744172Ssaidi@eecs.umich.edu Param<Tick> speed; 2754172Ssaidi@eecs.umich.edu Param<Tick> delay; 2764172Ssaidi@eecs.umich.edu SimObjectParam<EtherDump *> dump; 2774172Ssaidi@eecs.umich.edu 2782315SN/AEND_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 2792315SN/A 2802683Sktlim@umich.eduBEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink) 2812315SN/A 2822315SN/A INIT_PARAM(int1, "interface 1"), 2834172Ssaidi@eecs.umich.edu INIT_PARAM(int2, "interface 2"), 2842315SN/A INIT_PARAM_DFLT(speed, "link speed in bits per second", 100000000), 2854172Ssaidi@eecs.umich.edu INIT_PARAM_DFLT(delay, "transmit delay of packets in us", 0), 2864172Ssaidi@eecs.umich.edu INIT_PARAM_DFLT(dump, "object to dump network packets to", NULL) 2872315SN/A 2882315SN/AEND_INIT_SIM_OBJECT_PARAMS(EtherLink) 2893468Sgblack@eecs.umich.edu 2902315SN/ACREATE_SIM_OBJECT(EtherLink) 2912315SN/A{ 2922683Sktlim@umich.edu return new EtherLink(getInstanceName(), int1, int2, speed, delay, dump); 2932315SN/A} 2942315SN/A 2958733Sgeoffrey.blake@arm.comREGISTER_SIM_OBJECT("EtherLink", EtherLink) 2968733Sgeoffrey.blake@arm.com