etherlink.cc revision 1762
12155SN/A/* 22155SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32155SN/A * All rights reserved. 42155SN/A * 52155SN/A * Redistribution and use in source and binary forms, with or without 62155SN/A * modification, are permitted provided that the following conditions are 72155SN/A * met: redistributions of source code must retain the above copyright 82155SN/A * notice, this list of conditions and the following disclaimer; 92155SN/A * redistributions in binary form must reproduce the above copyright 102155SN/A * notice, this list of conditions and the following disclaimer in the 112155SN/A * documentation and/or other materials provided with the distribution; 122155SN/A * neither the name of the copyright holders nor the names of its 132155SN/A * contributors may be used to endorse or promote products derived from 142155SN/A * this software without specific prior written permission. 152155SN/A * 162155SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172155SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182155SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192155SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202155SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212155SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222155SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232155SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242155SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252155SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262155SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272155SN/A */ 282665Ssaidi@eecs.umich.edu 292665Ssaidi@eecs.umich.edu/* @file 302155SN/A * Device module for modelling a fixed bandwidth full duplex ethernet link 314202Sbinkertn@umich.edu */ 322155SN/A 339850Sandreas.hansson@arm.com#include <cmath> 349850Sandreas.hansson@arm.com#include <deque> 359850Sandreas.hansson@arm.com#include <string> 367768SAli.Saidi@ARM.com#include <vector> 377768SAli.Saidi@ARM.com 388887Sgeoffrey.blake@arm.com#include "base/trace.hh" 392766Sktlim@umich.edu#include "dev/etherdump.hh" 404486Sbinkertn@umich.edu#include "dev/etherint.hh" 414486Sbinkertn@umich.edu#include "dev/etherlink.hh" 424776Sgblack@eecs.umich.edu#include "dev/etherpkt.hh" 434776Sgblack@eecs.umich.edu#include "sim/builder.hh" 448739Sgblack@eecs.umich.edu#include "sim/serialize.hh" 456365Sgblack@eecs.umich.edu#include "sim/system.hh" 4610259SAndrew.Bardsley@arm.com#include "sim/root.hh" 474486Sbinkertn@umich.edu 484202Sbinkertn@umich.eduusing namespace std; 494202Sbinkertn@umich.edu 504202Sbinkertn@umich.eduEtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1, 514202Sbinkertn@umich.edu double rate, Tick delay, EtherDump *dump) 5210319SAndreas.Sandberg@ARM.com : SimObject(name) 534202Sbinkertn@umich.edu{ 544776Sgblack@eecs.umich.edu link[0] = new Link(name + ".link0", this, 0, rate, delay, dump); 558739Sgblack@eecs.umich.edu link[1] = new Link(name + ".link1", this, 1, rate, delay, dump); 566365Sgblack@eecs.umich.edu 574202Sbinkertn@umich.edu interface[0] = new Interface(name + ".int0", link[0], link[1]); 588777Sgblack@eecs.umich.edu interface[1] = new Interface(name + ".int1", link[1], link[0]); 594202Sbinkertn@umich.edu 609913Ssteve.reinhardt@amd.com interface[0]->setPeer(peer0); 614202Sbinkertn@umich.edu peer0->setPeer(interface[0]); 624202Sbinkertn@umich.edu interface[1]->setPeer(peer1); 635217Ssaidi@eecs.umich.edu peer1->setPeer(interface[1]); 644202Sbinkertn@umich.edu} 6510259SAndrew.Bardsley@arm.com 662155SN/AEtherLink::~EtherLink() 678793Sgblack@eecs.umich.edu{ 688793Sgblack@eecs.umich.edu delete link[0]; 698793Sgblack@eecs.umich.edu delete link[1]; 704776Sgblack@eecs.umich.edu 718887Sgeoffrey.blake@arm.com delete interface[0]; 7210201SAndrew.Bardsley@arm.com delete interface[1]; 738887Sgeoffrey.blake@arm.com} 749340SAndreas.Sandberg@arm.com 758887Sgeoffrey.blake@arm.comEtherLink::Interface::Interface(const string &name, Link *tx, Link *rx) 765192Ssaidi@eecs.umich.edu : EtherInt(name), txlink(tx) 778335Snate@binkert.org{ 788335Snate@binkert.org tx->setTxInt(this); 798335Snate@binkert.org rx->setRxInt(this); 808335Snate@binkert.org} 818335Snate@binkert.org 829534SAndreas.Sandberg@ARM.comEtherLink::Link::Link(const string &name, EtherLink *p, int num, 839534SAndreas.Sandberg@ARM.com double rate, Tick delay, EtherDump *d) 849534SAndreas.Sandberg@ARM.com : objName(name), parent(p), number(num), txint(NULL), rxint(NULL), 858335Snate@binkert.org ticksPerByte(rate), linkDelay(delay), dump(d), 869534SAndreas.Sandberg@ARM.com doneEvent(this) 879534SAndreas.Sandberg@ARM.com{ } 888335Snate@binkert.org 899534SAndreas.Sandberg@ARM.comvoid 909534SAndreas.Sandberg@ARM.comEtherLink::serialize(ostream &os) 919534SAndreas.Sandberg@ARM.com{ 929534SAndreas.Sandberg@ARM.com link[0]->serialize("link0", os); 939534SAndreas.Sandberg@ARM.com link[1]->serialize("link1", os); 949534SAndreas.Sandberg@ARM.com} 959534SAndreas.Sandberg@ARM.com 969534SAndreas.Sandberg@ARM.comvoid 979534SAndreas.Sandberg@ARM.comEtherLink::unserialize(Checkpoint *cp, const string §ion) 989534SAndreas.Sandberg@ARM.com{ 9910383Smitch.hayenga@arm.com link[0]->unserialize("link0", cp, section); 1008335Snate@binkert.org link[1]->unserialize("link1", cp, section); 1018335Snate@binkert.org} 1028471SGiacomo.Gabrielli@arm.com 1038335Snate@binkert.orgvoid 1048335Snate@binkert.orgEtherLink::Link::txComplete(PacketPtr packet) 10510529Smorr@cs.wisc.edu{ 1065192Ssaidi@eecs.umich.edu DPRINTF(Ethernet, "packet received: len=%d\n", packet->length); 1078232Snate@binkert.org DDUMP(EthernetData, packet->data, packet->length); 1088232Snate@binkert.org rxint->sendPacket(packet); 1098232Snate@binkert.org} 1108300Schander.sudanthi@arm.com 11110383Smitch.hayenga@arm.comclass LinkDelayEvent : public Event 1125192Ssaidi@eecs.umich.edu{ 1138300Schander.sudanthi@arm.com protected: 1148300Schander.sudanthi@arm.com EtherLink::Link *link; 1156036Sksewell@umich.edu PacketPtr packet; 1168300Schander.sudanthi@arm.com 1178300Schander.sudanthi@arm.com public: 118 // non-scheduling version for createForUnserialize() 119 LinkDelayEvent(); 120 LinkDelayEvent(EtherLink::Link *link, PacketPtr pkt, Tick when); 121 122 void process(); 123 124 virtual void serialize(ostream &os); 125 virtual void unserialize(Checkpoint *cp, const string §ion); 126 static Serializable *createForUnserialize(Checkpoint *cp, 127 const string §ion); 128}; 129 130void 131EtherLink::Link::txDone() 132{ 133 if (dump) 134 dump->dump(packet); 135 136 if (linkDelay > 0) { 137 DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay); 138 new LinkDelayEvent(this, packet, curTick + linkDelay); 139 } else { 140 txComplete(packet); 141 } 142 143 packet = 0; 144 assert(!busy()); 145 146 txint->sendDone(); 147} 148 149bool 150EtherLink::Link::transmit(PacketPtr pkt) 151{ 152 if (busy()) { 153 DPRINTF(Ethernet, "packet not sent, link busy\n"); 154 return false; 155 } 156 157 DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length); 158 DDUMP(EthernetData, pkt->data, pkt->length); 159 160 packet = pkt; 161 Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0); 162 DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", 163 delay, ticksPerByte); 164 doneEvent.schedule(curTick + delay); 165 166 return true; 167} 168 169void 170EtherLink::Link::serialize(const string &base, ostream &os) 171{ 172 bool packet_exists = packet; 173 paramOut(os, base + ".packet_exists", packet_exists); 174 if (packet_exists) 175 packet->serialize(base + ".packet", os); 176 177 bool event_scheduled = doneEvent.scheduled(); 178 paramOut(os, base + ".event_scheduled", event_scheduled); 179 if (event_scheduled) { 180 Tick event_time = doneEvent.when(); 181 paramOut(os, base + ".event_time", event_time); 182 } 183 184} 185 186void 187EtherLink::Link::unserialize(const string &base, Checkpoint *cp, 188 const string §ion) 189{ 190 bool packet_exists; 191 paramIn(cp, section, base + ".packet_exists", packet_exists); 192 if (packet_exists) { 193 packet = new PacketData(16384); 194 packet->unserialize(base + ".packet", cp, section); 195 } 196 197 bool event_scheduled; 198 paramIn(cp, section, base + ".event_scheduled", event_scheduled); 199 if (event_scheduled) { 200 Tick event_time; 201 paramIn(cp, section, base + ".event_time", event_time); 202 doneEvent.schedule(event_time); 203 } 204} 205 206LinkDelayEvent::LinkDelayEvent() 207 : Event(&mainEventQueue), link(NULL) 208{ 209 setFlags(AutoSerialize); 210 setFlags(AutoDelete); 211} 212 213LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, PacketPtr p, Tick when) 214 : Event(&mainEventQueue), link(l), packet(p) 215{ 216 setFlags(AutoSerialize); 217 setFlags(AutoDelete); 218 schedule(when); 219} 220 221void 222LinkDelayEvent::process() 223{ 224 link->txComplete(packet); 225} 226 227void 228LinkDelayEvent::serialize(ostream &os) 229{ 230 paramOut(os, "type", string("LinkDelayEvent")); 231 Event::serialize(os); 232 233 EtherLink *parent = link->parent; 234 bool number = link->number; 235 SERIALIZE_OBJPTR(parent); 236 SERIALIZE_SCALAR(number); 237 238 packet->serialize("packet", os); 239} 240 241 242void 243LinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) 244{ 245 Event::unserialize(cp, section); 246 247 EtherLink *parent; 248 bool number; 249 UNSERIALIZE_OBJPTR(parent); 250 UNSERIALIZE_SCALAR(number); 251 252 link = parent->link[number]; 253 254 packet = new PacketData(16384); 255 packet->unserialize("packet", cp, section); 256} 257 258 259Serializable * 260LinkDelayEvent::createForUnserialize(Checkpoint *cp, const string §ion) 261{ 262 return new LinkDelayEvent(); 263} 264 265REGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent) 266 267BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 268 269 SimObjectParam<EtherInt *> int1; 270 SimObjectParam<EtherInt *> int2; 271 Param<double> speed; 272 Param<Tick> delay; 273 SimObjectParam<EtherDump *> dump; 274 275END_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 276 277BEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink) 278 279 INIT_PARAM(int1, "interface 1"), 280 INIT_PARAM(int2, "interface 2"), 281 INIT_PARAM(speed, "link speed in bits per second"), 282 INIT_PARAM(delay, "transmit delay of packets in us"), 283 INIT_PARAM(dump, "object to dump network packets to") 284 285END_INIT_SIM_OBJECT_PARAMS(EtherLink) 286 287CREATE_SIM_OBJECT(EtherLink) 288{ 289 return new EtherLink(getInstanceName(), int1, int2, speed, delay, dump); 290} 291 292REGISTER_SIM_OBJECT("EtherLink", EtherLink) 293