etherlink.cc revision 1435
110952Satgutier@umich.edu/* 210952Satgutier@umich.edu * Copyright (c) 2002-2004 The Regents of The University of Michigan 310952Satgutier@umich.edu * All rights reserved. 410952Satgutier@umich.edu * 510952Satgutier@umich.edu * Redistribution and use in source and binary forms, with or without 610952Satgutier@umich.edu * modification, are permitted provided that the following conditions are 710952Satgutier@umich.edu * met: redistributions of source code must retain the above copyright 810952Satgutier@umich.edu * notice, this list of conditions and the following disclaimer; 910952Satgutier@umich.edu * redistributions in binary form must reproduce the above copyright 1010952Satgutier@umich.edu * notice, this list of conditions and the following disclaimer in the 1110952Satgutier@umich.edu * documentation and/or other materials provided with the distribution; 1210952Satgutier@umich.edu * neither the name of the copyright holders nor the names of its 1310952Satgutier@umich.edu * contributors may be used to endorse or promote products derived from 1410952Satgutier@umich.edu * this software without specific prior written permission. 1510952Satgutier@umich.edu * 1610952Satgutier@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1710952Satgutier@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1810952Satgutier@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1910952Satgutier@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2010952Satgutier@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2110952Satgutier@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2210952Satgutier@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2310952Satgutier@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2410952Satgutier@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2510952Satgutier@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2610952Satgutier@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2710952Satgutier@umich.edu */ 2810952Satgutier@umich.edu 2910952Satgutier@umich.edu/* @file 3010952Satgutier@umich.edu * Device module for modelling a fixed bandwidth full duplex ethernet link 3110952Satgutier@umich.edu */ 3210952Satgutier@umich.edu 3310952Satgutier@umich.edu#include <cmath> 3410952Satgutier@umich.edu#include <deque> 3510952Satgutier@umich.edu#include <string> 3610952Satgutier@umich.edu#include <vector> 3710952Satgutier@umich.edu 3810952Satgutier@umich.edu#include "base/trace.hh" 3910952Satgutier@umich.edu#include "dev/etherdump.hh" 4010952Satgutier@umich.edu#include "dev/etherint.hh" 4110952Satgutier@umich.edu#include "dev/etherlink.hh" 4210952Satgutier@umich.edu#include "dev/etherpkt.hh" 4310952Satgutier@umich.edu#include "sim/builder.hh" 4410952Satgutier@umich.edu#include "sim/serialize.hh" 4510952Satgutier@umich.edu#include "sim/system.hh" 4610952Satgutier@umich.edu#include "sim/universe.hh" 4710952Satgutier@umich.edu 4810952Satgutier@umich.eduusing namespace std; 4910952Satgutier@umich.edu 5010952Satgutier@umich.eduEtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1, 5110952Satgutier@umich.edu Tick speed, Tick dly, EtherDump *dump) 5210952Satgutier@umich.edu : SimObject(name) 5310952Satgutier@umich.edu{ 5410952Satgutier@umich.edu double rate = ((double)ticksPerSecond * 8.0) / (double)speed; 5510952Satgutier@umich.edu Tick delay = US2Ticks(dly); 5610952Satgutier@umich.edu 5710952Satgutier@umich.edu link[0] = new Link(name + ".link0", this, 0, rate, delay, dump); 5810952Satgutier@umich.edu link[1] = new Link(name + ".link1", this, 1, rate, delay, dump); 5910952Satgutier@umich.edu 6010952Satgutier@umich.edu interface[0] = new Interface(name + ".int0", link[0], link[1]); 6110952Satgutier@umich.edu interface[1] = new Interface(name + ".int1", link[1], link[0]); 6210952Satgutier@umich.edu 6310952Satgutier@umich.edu interface[0]->setPeer(peer0); 6410952Satgutier@umich.edu peer0->setPeer(interface[0]); 6510952Satgutier@umich.edu interface[1]->setPeer(peer1); 6610952Satgutier@umich.edu peer1->setPeer(interface[1]); 6710952Satgutier@umich.edu} 6810952Satgutier@umich.edu 6910952Satgutier@umich.eduEtherLink::~EtherLink() 7010952Satgutier@umich.edu{ 7110952Satgutier@umich.edu delete link[0]; 7210952Satgutier@umich.edu delete link[1]; 7310952Satgutier@umich.edu 7410952Satgutier@umich.edu delete interface[0]; 7510952Satgutier@umich.edu delete interface[1]; 7610952Satgutier@umich.edu} 7710952Satgutier@umich.edu 7810952Satgutier@umich.eduEtherLink::Interface::Interface(const string &name, Link *tx, Link *rx) 7910952Satgutier@umich.edu : EtherInt(name), txlink(tx) 8010952Satgutier@umich.edu{ 8110952Satgutier@umich.edu tx->setTxInt(this); 8210952Satgutier@umich.edu rx->setRxInt(this); 8310952Satgutier@umich.edu} 8410952Satgutier@umich.edu 8510952Satgutier@umich.eduEtherLink::Link::Link(const string &name, EtherLink *p, int num, 8610952Satgutier@umich.edu double rate, Tick delay, EtherDump *d) 8710952Satgutier@umich.edu : objName(name), parent(p), number(num), txint(NULL), rxint(NULL), 8810952Satgutier@umich.edu ticksPerByte(rate), linkDelay(delay), dump(d), 8910952Satgutier@umich.edu doneEvent(this) 9010952Satgutier@umich.edu{ } 9110952Satgutier@umich.edu 92void 93EtherLink::serialize(ostream &os) 94{ 95 link[0]->serialize("link0", os); 96 link[1]->serialize("link1", os); 97} 98 99void 100EtherLink::unserialize(Checkpoint *cp, const string §ion) 101{ 102 link[0]->unserialize("link0", cp, section); 103 link[1]->unserialize("link1", cp, section); 104} 105 106void 107EtherLink::Link::txComplete(PacketPtr packet) 108{ 109 DPRINTF(Ethernet, "packet received: len=%d\n", packet->length); 110 DDUMP(EthernetData, packet->data, packet->length); 111 rxint->sendPacket(packet); 112} 113 114class LinkDelayEvent : public Event 115{ 116 protected: 117 EtherLink::Link *link; 118 PacketPtr packet; 119 120 public: 121 // non-scheduling version for createForUnserialize() 122 LinkDelayEvent(); 123 LinkDelayEvent(EtherLink::Link *link, PacketPtr pkt, Tick when); 124 125 void process(); 126 127 virtual void serialize(ostream &os); 128 virtual void unserialize(Checkpoint *cp, const string §ion); 129 static Serializable *createForUnserialize(Checkpoint *cp, 130 const string §ion); 131}; 132 133void 134EtherLink::Link::txDone() 135{ 136 if (dump) 137 dump->dump(packet); 138 139 if (linkDelay > 0) { 140 DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay); 141 new LinkDelayEvent(this, packet, curTick + linkDelay); 142 } else { 143 txComplete(packet); 144 } 145 146 packet = 0; 147 assert(!busy()); 148 149 txint->sendDone(); 150} 151 152bool 153EtherLink::Link::transmit(PacketPtr pkt) 154{ 155 if (busy()) { 156 DPRINTF(Ethernet, "packet not sent, link busy\n"); 157 return false; 158 } 159 160 DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length); 161 DDUMP(EthernetData, pkt->data, pkt->length); 162 163 packet = pkt; 164 Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0); 165 DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", 166 delay, ticksPerByte); 167 doneEvent.schedule(curTick + delay); 168 169 return true; 170} 171 172void 173EtherLink::Link::serialize(const string &base, ostream &os) 174{ 175 bool packet_exists = packet; 176 paramOut(os, base + ".packet_exists", packet_exists); 177 if (packet_exists) 178 packet->serialize(base + ".packet", os); 179 180 bool event_scheduled = doneEvent.scheduled(); 181 paramOut(os, base + ".event_scheuled", event_scheduled); 182 if (event_scheduled) { 183 Tick event_time = doneEvent.when(); 184 paramOut(os, base + ".event_time", event_time); 185 } 186 187} 188 189void 190EtherLink::Link::unserialize(const string &base, Checkpoint *cp, 191 const string §ion) 192{ 193 bool packet_exists; 194 paramIn(cp, section, base + ".packet_exists", packet_exists); 195 if (packet_exists) { 196 packet = new PacketData(16384); 197 packet->unserialize(base + ".packet", cp, section); 198 } 199 200 bool event_scheduled; 201 paramIn(cp, section, base + ".event_scheduled", event_scheduled); 202 if (event_scheduled) { 203 Tick event_time; 204 paramIn(cp, section, base + ".event_time", event_time); 205 doneEvent.schedule(event_time); 206 } 207} 208 209LinkDelayEvent::LinkDelayEvent() 210 : Event(&mainEventQueue), link(NULL) 211{ 212 setFlags(AutoSerialize); 213 setFlags(AutoDelete); 214} 215 216LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, PacketPtr p, Tick when) 217 : Event(&mainEventQueue), link(l), packet(p) 218{ 219 setFlags(AutoSerialize); 220 setFlags(AutoDelete); 221 schedule(when); 222} 223 224void 225LinkDelayEvent::process() 226{ 227 link->txComplete(packet); 228} 229 230void 231LinkDelayEvent::serialize(ostream &os) 232{ 233 paramOut(os, "type", string("LinkDelayEvent")); 234 Event::serialize(os); 235 236 EtherLink *parent = link->parent; 237 bool number = link->number; 238 SERIALIZE_OBJPTR(parent); 239 SERIALIZE_SCALAR(number); 240 241 packet->serialize("packet", os); 242} 243 244 245void 246LinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) 247{ 248 Event::unserialize(cp, section); 249 250 EtherLink *parent; 251 bool number; 252 UNSERIALIZE_OBJPTR(parent); 253 UNSERIALIZE_SCALAR(number); 254 255 link = parent->link[number]; 256 257 packet = new PacketData(16384); 258 packet->unserialize("packet", cp, section); 259} 260 261 262Serializable * 263LinkDelayEvent::createForUnserialize(Checkpoint *cp, const string §ion) 264{ 265 return new LinkDelayEvent(); 266} 267 268REGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent) 269 270BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 271 272 SimObjectParam<EtherInt *> int1; 273 SimObjectParam<EtherInt *> int2; 274 Param<Tick> speed; 275 Param<Tick> delay; 276 SimObjectParam<EtherDump *> dump; 277 278END_DECLARE_SIM_OBJECT_PARAMS(EtherLink) 279 280BEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink) 281 282 INIT_PARAM(int1, "interface 1"), 283 INIT_PARAM(int2, "interface 2"), 284 INIT_PARAM_DFLT(speed, "link speed in bits per second", 100000000), 285 INIT_PARAM_DFLT(delay, "transmit delay of packets in us", 0), 286 INIT_PARAM_DFLT(dump, "object to dump network packets to", NULL) 287 288END_INIT_SIM_OBJECT_PARAMS(EtherLink) 289 290CREATE_SIM_OBJECT(EtherLink) 291{ 292 return new EtherLink(getInstanceName(), int1, int2, speed, delay, dump); 293} 294 295REGISTER_SIM_OBJECT("EtherLink", EtherLink) 296