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