dist_etherlink.cc revision 11263
14484Sbinkertn@umich.edu/* 24484Sbinkertn@umich.edu * Copyright (c) 2015 ARM Limited 34484Sbinkertn@umich.edu * All rights reserved 44484Sbinkertn@umich.edu * 54484Sbinkertn@umich.edu * The license below extends only to copyright in the software and shall 64484Sbinkertn@umich.edu * not be construed as granting a license to any other intellectual 74484Sbinkertn@umich.edu * property including but not limited to intellectual property relating 84484Sbinkertn@umich.edu * to a hardware implementation of the functionality of the software 94484Sbinkertn@umich.edu * licensed hereunder. You may use the software subject to the license 104484Sbinkertn@umich.edu * terms below provided that you ensure that this notice is replicated 114484Sbinkertn@umich.edu * unmodified and in its entirety in all distributions of the software, 124484Sbinkertn@umich.edu * modified or unmodified, in source code or in binary form. 134484Sbinkertn@umich.edu * 144484Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without 154484Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are 164484Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright 174484Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer; 184484Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright 194484Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the 204484Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution; 214484Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its 224484Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from 234484Sbinkertn@umich.edu * this software without specific prior written permission. 244484Sbinkertn@umich.edu * 254484Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 264484Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 274484Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 284484Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 294484Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 304484Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 314484Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 324484Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 334484Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 344484Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 354484Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 364484Sbinkertn@umich.edu * 374484Sbinkertn@umich.edu * Authors: Gabor Dozsa 384484Sbinkertn@umich.edu */ 394484Sbinkertn@umich.edu 404484Sbinkertn@umich.edu/* @file 414484Sbinkertn@umich.edu * Device module for a full duplex ethernet link for multi gem5 simulations. 424484Sbinkertn@umich.edu */ 434484Sbinkertn@umich.edu 444484Sbinkertn@umich.edu#include "dev/net/multi_etherlink.hh" 454484Sbinkertn@umich.edu 464484Sbinkertn@umich.edu#include <arpa/inet.h> 474484Sbinkertn@umich.edu#include <sys/socket.h> 484484Sbinkertn@umich.edu#include <unistd.h> 494484Sbinkertn@umich.edu 504484Sbinkertn@umich.edu#include <cmath> 514484Sbinkertn@umich.edu#include <deque> 524484Sbinkertn@umich.edu#include <string> 534484Sbinkertn@umich.edu#include <vector> 544484Sbinkertn@umich.edu 554484Sbinkertn@umich.edu#include "base/random.hh" 564484Sbinkertn@umich.edu#include "base/trace.hh" 574484Sbinkertn@umich.edu#include "debug/EthernetData.hh" 584484Sbinkertn@umich.edu#include "debug/MultiEthernet.hh" 594484Sbinkertn@umich.edu#include "debug/MultiEthernetPkt.hh" 604484Sbinkertn@umich.edu#include "dev/net/etherdump.hh" 614484Sbinkertn@umich.edu#include "dev/net/etherint.hh" 624484Sbinkertn@umich.edu#include "dev/net/etherlink.hh" 634484Sbinkertn@umich.edu#include "dev/net/etherobject.hh" 644484Sbinkertn@umich.edu#include "dev/net/etherpkt.hh" 654484Sbinkertn@umich.edu#include "dev/net/multi_iface.hh" 664484Sbinkertn@umich.edu#include "dev/net/tcp_iface.hh" 674484Sbinkertn@umich.edu#include "params/EtherLink.hh" 684484Sbinkertn@umich.edu#include "sim/core.hh" 694484Sbinkertn@umich.edu#include "sim/serialize.hh" 704484Sbinkertn@umich.edu#include "sim/system.hh" 714484Sbinkertn@umich.edu 724484Sbinkertn@umich.eduusing namespace std; 734484Sbinkertn@umich.edu 744484Sbinkertn@umich.eduMultiEtherLink::MultiEtherLink(const Params *p) 754484Sbinkertn@umich.edu : EtherObject(p) 764484Sbinkertn@umich.edu{ 774484Sbinkertn@umich.edu DPRINTF(MultiEthernet,"MultiEtherLink::MultiEtherLink() " 784484Sbinkertn@umich.edu "link delay:%llu\n", p->delay); 794484Sbinkertn@umich.edu 804484Sbinkertn@umich.edu txLink = new TxLink(name() + ".link0", this, p->speed, p->delay_var, 814484Sbinkertn@umich.edu p->dump); 824484Sbinkertn@umich.edu rxLink = new RxLink(name() + ".link1", this, p->delay, p->dump); 834484Sbinkertn@umich.edu 844484Sbinkertn@umich.edu // create the multi (TCP) interface to talk to the peer gem5 processes. 854484Sbinkertn@umich.edu multiIface = new TCPIface(p->server_name, p->server_port, p->multi_rank, 864484Sbinkertn@umich.edu p->sync_start, p->sync_repeat, this); 874484Sbinkertn@umich.edu 884484Sbinkertn@umich.edu localIface = new LocalIface(name() + ".int0", txLink, rxLink, multiIface); 894484Sbinkertn@umich.edu} 904484Sbinkertn@umich.edu 914484Sbinkertn@umich.eduMultiEtherLink::~MultiEtherLink() 924484Sbinkertn@umich.edu{ 934484Sbinkertn@umich.edu delete txLink; 944484Sbinkertn@umich.edu delete rxLink; 954484Sbinkertn@umich.edu delete localIface; 964484Sbinkertn@umich.edu delete multiIface; 974484Sbinkertn@umich.edu} 984484Sbinkertn@umich.edu 994484Sbinkertn@umich.eduEtherInt* 1004484Sbinkertn@umich.eduMultiEtherLink::getEthPort(const std::string &if_name, int idx) 1014484Sbinkertn@umich.edu{ 1024484Sbinkertn@umich.edu if (if_name != "int0") { 1034484Sbinkertn@umich.edu return nullptr; 1044484Sbinkertn@umich.edu } else { 1054484Sbinkertn@umich.edu panic_if(localIface->getPeer(), "interface already connected to"); 1064484Sbinkertn@umich.edu } 1074484Sbinkertn@umich.edu return localIface; 1084484Sbinkertn@umich.edu} 1094484Sbinkertn@umich.edu 1104484Sbinkertn@umich.eduvoid MultiEtherLink::memWriteback() 1114484Sbinkertn@umich.edu{ 1124484Sbinkertn@umich.edu DPRINTF(MultiEthernet,"MultiEtherLink::memWriteback() called\n"); 1134484Sbinkertn@umich.edu multiIface->drainDone(); 1144484Sbinkertn@umich.edu} 1154484Sbinkertn@umich.edu 1164484Sbinkertn@umich.eduvoid 1174484Sbinkertn@umich.eduMultiEtherLink::serialize(CheckpointOut &cp) const 1184484Sbinkertn@umich.edu{ 1194484Sbinkertn@umich.edu multiIface->serialize("multiIface", cp); 1204484Sbinkertn@umich.edu txLink->serialize("txLink", cp); 1214484Sbinkertn@umich.edu rxLink->serialize("rxLink", cp); 1224484Sbinkertn@umich.edu} 1234484Sbinkertn@umich.edu 1244484Sbinkertn@umich.eduvoid 1254484Sbinkertn@umich.eduMultiEtherLink::unserialize(CheckpointIn &cp) 1264484Sbinkertn@umich.edu{ 1274484Sbinkertn@umich.edu multiIface->unserialize("multiIface", cp); 1284484Sbinkertn@umich.edu txLink->unserialize("txLink", cp); 1294484Sbinkertn@umich.edu rxLink->unserialize("rxLink", cp); 1304484Sbinkertn@umich.edu} 1314484Sbinkertn@umich.edu 1324484Sbinkertn@umich.eduvoid 1334484Sbinkertn@umich.eduMultiEtherLink::init() 1344484Sbinkertn@umich.edu{ 1354484Sbinkertn@umich.edu DPRINTF(MultiEthernet,"MultiEtherLink::init() called\n"); 1364484Sbinkertn@umich.edu multiIface->initRandom(); 1374484Sbinkertn@umich.edu} 1384484Sbinkertn@umich.edu 1394484Sbinkertn@umich.eduvoid 1404484Sbinkertn@umich.eduMultiEtherLink::startup() 1414484Sbinkertn@umich.edu{ 1424484Sbinkertn@umich.edu DPRINTF(MultiEthernet,"MultiEtherLink::startup() called\n"); 1434484Sbinkertn@umich.edu multiIface->startPeriodicSync(); 1444484Sbinkertn@umich.edu} 1454484Sbinkertn@umich.edu 1464484Sbinkertn@umich.eduvoid 1474484Sbinkertn@umich.eduMultiEtherLink::RxLink::setMultiInt(MultiIface *m) 1484484Sbinkertn@umich.edu{ 1494484Sbinkertn@umich.edu assert(!multiIface); 1504484Sbinkertn@umich.edu multiIface = m; 1514484Sbinkertn@umich.edu // Spawn a new receiver thread that will process messages 1524484Sbinkertn@umich.edu // coming in from peer gem5 processes. 1534484Sbinkertn@umich.edu // The receive thread will also schedule a (receive) doneEvent 1544484Sbinkertn@umich.edu // for each incoming data packet. 1554484Sbinkertn@umich.edu multiIface->spawnRecvThread(&doneEvent, linkDelay); 1564484Sbinkertn@umich.edu} 1574484Sbinkertn@umich.edu 1584484Sbinkertn@umich.eduvoid 1594484Sbinkertn@umich.eduMultiEtherLink::RxLink::rxDone() 1604484Sbinkertn@umich.edu{ 1614484Sbinkertn@umich.edu assert(!busy()); 1624484Sbinkertn@umich.edu 1634484Sbinkertn@umich.edu // retrieve the packet that triggered the receive done event 1644484Sbinkertn@umich.edu packet = multiIface->packetIn(); 1654484Sbinkertn@umich.edu 1664484Sbinkertn@umich.edu if (dump) 1674484Sbinkertn@umich.edu dump->dump(packet); 1684484Sbinkertn@umich.edu 1694484Sbinkertn@umich.edu DPRINTF(MultiEthernetPkt, "MultiEtherLink::MultiLink::rxDone() " 1704484Sbinkertn@umich.edu "packet received: len=%d\n", packet->length); 1714484Sbinkertn@umich.edu DDUMP(EthernetData, packet->data, packet->length); 1724484Sbinkertn@umich.edu 1734484Sbinkertn@umich.edu localIface->sendPacket(packet); 1744484Sbinkertn@umich.edu 1754484Sbinkertn@umich.edu packet = nullptr; 1764484Sbinkertn@umich.edu} 1774484Sbinkertn@umich.edu 1784484Sbinkertn@umich.eduvoid 1794484Sbinkertn@umich.eduMultiEtherLink::TxLink::txDone() 1804484Sbinkertn@umich.edu{ 1814484Sbinkertn@umich.edu if (dump) 1824484Sbinkertn@umich.edu dump->dump(packet); 1834484Sbinkertn@umich.edu 1844484Sbinkertn@umich.edu packet = nullptr; 1854484Sbinkertn@umich.edu assert(!busy()); 1864484Sbinkertn@umich.edu 1874484Sbinkertn@umich.edu localIface->sendDone(); 1884484Sbinkertn@umich.edu} 1894484Sbinkertn@umich.edu 1904484Sbinkertn@umich.edubool 1914484Sbinkertn@umich.eduMultiEtherLink::TxLink::transmit(EthPacketPtr pkt) 1924484Sbinkertn@umich.edu{ 1934484Sbinkertn@umich.edu if (busy()) { 1944484Sbinkertn@umich.edu DPRINTF(MultiEthernet, "packet not sent, link busy\n"); 1954484Sbinkertn@umich.edu return false; 1964484Sbinkertn@umich.edu } 1974484Sbinkertn@umich.edu 1984484Sbinkertn@umich.edu packet = pkt; 1994484Sbinkertn@umich.edu Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0); 2004484Sbinkertn@umich.edu if (delayVar != 0) 2014484Sbinkertn@umich.edu delay += random_mt.random<Tick>(0, delayVar); 2024484Sbinkertn@umich.edu 2034484Sbinkertn@umich.edu // send the packet to the peers 2044484Sbinkertn@umich.edu assert(multiIface); 2054484Sbinkertn@umich.edu multiIface->packetOut(pkt, delay); 2064484Sbinkertn@umich.edu 2074484Sbinkertn@umich.edu // schedule the send done event 2084484Sbinkertn@umich.edu parent->schedule(doneEvent, curTick() + delay); 2094484Sbinkertn@umich.edu 2104484Sbinkertn@umich.edu return true; 2114484Sbinkertn@umich.edu} 2124484Sbinkertn@umich.edu 2134484Sbinkertn@umich.eduvoid 2144484Sbinkertn@umich.eduMultiEtherLink::Link::serialize(const string &base, CheckpointOut &cp) const 2154484Sbinkertn@umich.edu{ 2164484Sbinkertn@umich.edu bool packet_exists = (packet != nullptr); 2174484Sbinkertn@umich.edu paramOut(cp, base + ".packet_exists", packet_exists); 2184484Sbinkertn@umich.edu if (packet_exists) 2194484Sbinkertn@umich.edu packet->serialize(base + ".packet", cp); 2204484Sbinkertn@umich.edu 2214484Sbinkertn@umich.edu bool event_scheduled = event->scheduled(); 2224484Sbinkertn@umich.edu paramOut(cp, base + ".event_scheduled", event_scheduled); 2234484Sbinkertn@umich.edu if (event_scheduled) { 2244484Sbinkertn@umich.edu Tick event_time = event->when(); 2254484Sbinkertn@umich.edu paramOut(cp, base + ".event_time", event_time); 2264484Sbinkertn@umich.edu } 2274484Sbinkertn@umich.edu} 2284484Sbinkertn@umich.edu 2294484Sbinkertn@umich.eduvoid 2304484Sbinkertn@umich.eduMultiEtherLink::Link::unserialize(const string &base, CheckpointIn &cp) 2314484Sbinkertn@umich.edu{ 2324484Sbinkertn@umich.edu bool packet_exists; 2334484Sbinkertn@umich.edu paramIn(cp, base + ".packet_exists", packet_exists); 2344484Sbinkertn@umich.edu if (packet_exists) { 2354484Sbinkertn@umich.edu packet = make_shared<EthPacketData>(16384); 2364484Sbinkertn@umich.edu packet->unserialize(base + ".packet", cp); 2374484Sbinkertn@umich.edu } 2384484Sbinkertn@umich.edu 2394484Sbinkertn@umich.edu bool event_scheduled; 2404484Sbinkertn@umich.edu paramIn(cp, base + ".event_scheduled", event_scheduled); 2414484Sbinkertn@umich.edu if (event_scheduled) { 2424484Sbinkertn@umich.edu Tick event_time; 2434484Sbinkertn@umich.edu paramIn(cp, base + ".event_time", event_time); 2444484Sbinkertn@umich.edu parent->schedule(*event, event_time); 2454484Sbinkertn@umich.edu } 2464484Sbinkertn@umich.edu} 2474484Sbinkertn@umich.edu 2484484Sbinkertn@umich.eduMultiEtherLink::LocalIface::LocalIface(const std::string &name, 2494484Sbinkertn@umich.edu TxLink *tx, 2504484Sbinkertn@umich.edu RxLink *rx, 2514484Sbinkertn@umich.edu MultiIface *m) : 2524484Sbinkertn@umich.edu EtherInt(name), txLink(tx) 2534484Sbinkertn@umich.edu{ 2544484Sbinkertn@umich.edu tx->setLocalInt(this); 2554484Sbinkertn@umich.edu rx->setLocalInt(this); 2564484Sbinkertn@umich.edu tx->setMultiInt(m); 2574484Sbinkertn@umich.edu rx->setMultiInt(m); 2584484Sbinkertn@umich.edu} 2594484Sbinkertn@umich.edu 2604484Sbinkertn@umich.eduMultiEtherLink * 2614484Sbinkertn@umich.eduMultiEtherLinkParams::create() 2624484Sbinkertn@umich.edu{ 2634484Sbinkertn@umich.edu return new MultiEtherLink(this); 2644484Sbinkertn@umich.edu} 2654484Sbinkertn@umich.edu 2664484Sbinkertn@umich.edu 2674484Sbinkertn@umich.edu