etherbus.cc revision 1634
113207Sgabeblack@google.com/* 213207Sgabeblack@google.com * Copyright (c) 2002-2004 The Regents of The University of Michigan 313207Sgabeblack@google.com * All rights reserved. 413207Sgabeblack@google.com * 513207Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 613207Sgabeblack@google.com * modification, are permitted provided that the following conditions are 713207Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 813207Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 913207Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1013207Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1113207Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1213207Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1313207Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1413207Sgabeblack@google.com * this software without specific prior written permission. 1513207Sgabeblack@google.com * 1613207Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1713207Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1813207Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1913207Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2013207Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2113207Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2213207Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2313207Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2413207Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2513207Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2613207Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2713207Sgabeblack@google.com */ 2813207Sgabeblack@google.com 2913207Sgabeblack@google.com/* @file 3013207Sgabeblack@google.com * Device module for modelling an ethernet hub 3113207Sgabeblack@google.com */ 3213207Sgabeblack@google.com 3313207Sgabeblack@google.com#include <cmath> 3413273Sgabeblack@google.com#include <deque> 3513207Sgabeblack@google.com#include <string> 3613207Sgabeblack@google.com#include <vector> 3713239Sgabeblack@google.com 3813207Sgabeblack@google.com#include "base/trace.hh" 3913207Sgabeblack@google.com#include "dev/etherbus.hh" 4013207Sgabeblack@google.com#include "dev/etherdump.hh" 4113207Sgabeblack@google.com#include "dev/etherint.hh" 4213207Sgabeblack@google.com#include "dev/etherpkt.hh" 4313207Sgabeblack@google.com#include "sim/builder.hh" 4413207Sgabeblack@google.com#include "sim/universe.hh" 4513207Sgabeblack@google.com 4613288Sgabeblack@google.comusing namespace std; 4713207Sgabeblack@google.com 4813207Sgabeblack@google.comEtherBus::EtherBus(const string &name, double speed, bool loop, 4913207Sgabeblack@google.com EtherDump *packet_dump) 5013207Sgabeblack@google.com : SimObject(name), ticksPerByte(speed), loopback(loop), 5113207Sgabeblack@google.com event(&mainEventQueue, this), sender(0), dump(packet_dump) 5213207Sgabeblack@google.com{ 5313207Sgabeblack@google.com} 5413207Sgabeblack@google.com 5513207Sgabeblack@google.comvoid 5613207Sgabeblack@google.comEtherBus::txDone() 5713207Sgabeblack@google.com{ 5813207Sgabeblack@google.com devlist_t::iterator i = devlist.begin(); 5913207Sgabeblack@google.com devlist_t::iterator end = devlist.end(); 6013207Sgabeblack@google.com 6113273Sgabeblack@google.com DPRINTF(Ethernet, "ethernet packet received: length=%d\n", packet->length); 6213273Sgabeblack@google.com DDUMP(EthernetData, packet->data, packet->length); 6313207Sgabeblack@google.com 6413207Sgabeblack@google.com while (i != end) { 6513288Sgabeblack@google.com if (loopback || *i != sender) 6613207Sgabeblack@google.com (*i)->sendPacket(packet); 6713207Sgabeblack@google.com ++i; 6813239Sgabeblack@google.com } 6913207Sgabeblack@google.com 7013321Sgabeblack@google.com sender->sendDone(); 7113207Sgabeblack@google.com 7213207Sgabeblack@google.com if (dump) 7313207Sgabeblack@google.com dump->dump(packet); 7413207Sgabeblack@google.com 7513207Sgabeblack@google.com sender = 0; 7613207Sgabeblack@google.com packet = 0; 7713273Sgabeblack@google.com} 7813273Sgabeblack@google.com 7913207Sgabeblack@google.comvoid 8013207Sgabeblack@google.comEtherBus::reg(EtherInt *dev) 8113207Sgabeblack@google.com{ devlist.push_back(dev); } 8213207Sgabeblack@google.com 8313207Sgabeblack@google.combool 8413207Sgabeblack@google.comEtherBus::send(EtherInt *sndr, PacketPtr &pkt) 8513207Sgabeblack@google.com{ 8613207Sgabeblack@google.com if (busy()) { 8713207Sgabeblack@google.com DPRINTF(Ethernet, "ethernet packet not sent, bus busy\n", curTick); 8813207Sgabeblack@google.com return false; 8913207Sgabeblack@google.com } 9013207Sgabeblack@google.com 9113207Sgabeblack@google.com DPRINTF(Ethernet, "ethernet packet sent: length=%d\n", pkt->length); 9213207Sgabeblack@google.com DDUMP(EthernetData, pkt->data, pkt->length); 9313207Sgabeblack@google.com 9413207Sgabeblack@google.com packet = pkt; 9513207Sgabeblack@google.com sender = sndr; 9613207Sgabeblack@google.com int delay = (int)ceil(((double)pkt->length * ticksPerByte) + 1.0); 9713207Sgabeblack@google.com DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", 9813207Sgabeblack@google.com delay, ticksPerByte); 9913207Sgabeblack@google.com event.schedule(curTick + delay); 10013207Sgabeblack@google.com 10113207Sgabeblack@google.com return true; 10213207Sgabeblack@google.com} 10313207Sgabeblack@google.com 10413207Sgabeblack@google.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherBus) 10513207Sgabeblack@google.com 10613288Sgabeblack@google.com Param<bool> loopback; 10713207Sgabeblack@google.com Param<double> speed; 10813207Sgabeblack@google.com SimObjectParam<EtherDump *> packet_dump; 10913207Sgabeblack@google.com 11013288Sgabeblack@google.comEND_DECLARE_SIM_OBJECT_PARAMS(EtherBus) 11113207Sgabeblack@google.com 11213207Sgabeblack@google.comBEGIN_INIT_SIM_OBJECT_PARAMS(EtherBus) 11313207Sgabeblack@google.com 11413207Sgabeblack@google.com INIT_PARAM(loopback, "send the packet back to the sending interface"), 11513207Sgabeblack@google.com INIT_PARAM(speed, "bus speed in ticks per byte"), 11613207Sgabeblack@google.com INIT_PARAM(packet_dump, "object to dump network packets to") 11713207Sgabeblack@google.com 11813207Sgabeblack@google.comEND_INIT_SIM_OBJECT_PARAMS(EtherBus) 11913288Sgabeblack@google.com 12013207Sgabeblack@google.comCREATE_SIM_OBJECT(EtherBus) 12113207Sgabeblack@google.com{ 12213207Sgabeblack@google.com return new EtherBus(getInstanceName(), speed, loopback, packet_dump); 12313207Sgabeblack@google.com} 12413207Sgabeblack@google.com 12513207Sgabeblack@google.comREGISTER_SIM_OBJECT("EtherBus", EtherBus) 12613207Sgabeblack@google.com