gem5 v24.1.0.1
Loading...
Searching...
No Matches
etherlink.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41/* @file
42 * Device module for modelling a fixed bandwidth full duplex ethernet link
43 */
44
45#include "dev/net/etherlink.hh"
46
47#include <cassert>
48#include <cmath>
49#include <deque>
50#include <string>
51#include <vector>
52
53#include "base/logging.hh"
54#include "base/trace.hh"
55#include "debug/Ethernet.hh"
56#include "debug/EthernetData.hh"
57#include "dev/net/etherdump.hh"
58#include "dev/net/etherint.hh"
59#include "dev/net/etherpkt.hh"
60#include "params/EtherLink.hh"
61#include "sim/cur_tick.hh"
62#include "sim/serialize.hh"
63#include "sim/system.hh"
64
65namespace gem5
66{
67
69 : SimObject(p)
70{
71 link[0] = new Link(name() + ".link0", this, 0, p.speed,
72 p.delay, p.delay_var, p.dump);
73 link[1] = new Link(name() + ".link1", this, 1, p.speed,
74 p.delay, p.delay_var, p.dump);
75
76 interface[0] = new Interface(name() + ".int0", link[0], link[1]);
77 interface[1] = new Interface(name() + ".int1", link[1], link[0]);
78}
79
80
82{
83 delete link[0];
84 delete link[1];
85
86 delete interface[0];
87 delete interface[1];
88}
89
90Port &
91EtherLink::getPort(const std::string &if_name, PortID idx)
92{
93 if (if_name == "int0")
94 return *interface[0];
95 else if (if_name == "int1")
96 return *interface[1];
97 return SimObject::getPort(if_name, idx);
98}
99
100
101EtherLink::Interface::Interface(const std::string &name, Link *tx, Link *rx)
102 : EtherInt(name), txlink(tx)
103{
104 tx->setTxInt(this);
105 rx->setRxInt(this);
106}
107
108EtherLink::Link::Link(const std::string &name, EtherLink *p, int num,
109 double rate, Tick delay, Tick delay_var, EtherDump *d)
110 : objName(name), parent(p), number(num), txint(NULL), rxint(NULL),
111 ticksPerByte(rate), linkDelay(delay), delayVar(delay_var), dump(d),
112 doneEvent([this]{ txDone(); }, name),
113 txQueueEvent([this]{ processTxQueue(); }, name)
114{ }
115
116void
118{
119 link[0]->serialize("link0", cp);
120 link[1]->serialize("link1", cp);
121}
122
123void
125{
126 link[0]->unserialize("link0", cp);
127 link[1]->unserialize("link1", cp);
128}
129
130void
132{
133 DPRINTF(Ethernet, "packet received: len=%d\n", packet->length);
134 DDUMP(EthernetData, packet->data, packet->length);
135 rxint->sendPacket(packet);
136}
137
138void
140{
141 if (dump)
142 dump->dump(packet);
143
144 if (linkDelay > 0) {
145 DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay);
146 txQueue.emplace_back(std::make_pair(curTick() + linkDelay, packet));
147 if (!txQueueEvent.scheduled())
148 parent->schedule(txQueueEvent, txQueue.front().first);
149 } else {
150 assert(txQueue.empty());
151 txComplete(packet);
152 }
153
154 packet = 0;
155 assert(!busy());
156
157 txint->sendDone();
158}
159
160void
162{
163 auto cur(txQueue.front());
164 txQueue.pop_front();
165
166 // Schedule a new event to process the next packet in the queue.
167 if (!txQueue.empty()) {
168 auto next(txQueue.front());
169 assert(next.first > curTick());
170 parent->schedule(txQueueEvent, next.first);
171 }
172
173 assert(cur.first == curTick());
174 txComplete(cur.second);
175}
176
177bool
179{
180 if (busy()) {
181 DPRINTF(Ethernet, "packet not sent, link busy\n");
182 return false;
183 }
184
185 DPRINTF(Ethernet, "packet sent: len=%d\n", pkt->length);
186 DDUMP(EthernetData, pkt->data, pkt->length);
187
188 packet = pkt;
189 Tick delay = (Tick)ceil(((double)pkt->simLength * ticksPerByte) + 1.0);
190 if (delayVar != 0)
191 delay += rng->random<Tick>(0, delayVar);
192
193 DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
194 delay, ticksPerByte);
195 parent->schedule(doneEvent, curTick() + delay);
196
197 return true;
198}
199
200void
201EtherLink::Link::serialize(const std::string &base, CheckpointOut &cp) const
202{
203 bool packet_exists = packet != nullptr;
204 paramOut(cp, base + ".packet_exists", packet_exists);
205 if (packet_exists)
206 packet->serialize(base + ".packet", cp);
207
208 bool event_scheduled = doneEvent.scheduled();
209 paramOut(cp, base + ".event_scheduled", event_scheduled);
210 if (event_scheduled) {
211 Tick event_time = doneEvent.when();
212 paramOut(cp, base + ".event_time", event_time);
213 }
214
215 const size_t tx_queue_size(txQueue.size());
216 paramOut(cp, base + ".tx_queue_size", tx_queue_size);
217 unsigned idx(0);
218 for (const auto &pe : txQueue) {
219 paramOut(cp, csprintf("%s.txQueue[%i].tick", base, idx), pe.first);
220 pe.second->serialize(csprintf("%s.txQueue[%i].packet", base, idx), cp);
221
222 ++idx;
223 }
224}
225
226void
228{
229 bool packet_exists;
230 paramIn(cp, base + ".packet_exists", packet_exists);
231 if (packet_exists) {
232 packet = std::make_shared<EthPacketData>();
233 packet->unserialize(base + ".packet", cp);
234 }
235
236 bool event_scheduled;
237 paramIn(cp, base + ".event_scheduled", event_scheduled);
238 if (event_scheduled) {
239 Tick event_time;
240 paramIn(cp, base + ".event_time", event_time);
241 parent->schedule(doneEvent, event_time);
242 }
243
244 size_t tx_queue_size = 0;
245 if (optParamIn(cp, base + ".tx_queue_size", tx_queue_size)) {
246 for (size_t idx = 0; idx < tx_queue_size; ++idx) {
247 Tick tick;
248 EthPacketPtr delayed_packet = std::make_shared<EthPacketData>();
249
250 paramIn(cp, csprintf("%s.txQueue[%i].tick", base, idx), tick);
251 delayed_packet->unserialize(
252 csprintf("%s.txQueue[%i].packet", base, idx), cp);
253
254 fatal_if(!txQueue.empty() && txQueue.back().first > tick,
255 "Invalid txQueue packet order in EtherLink!\n");
256 txQueue.emplace_back(std::make_pair(tick, delayed_packet));
257 }
258
259 if (!txQueue.empty())
260 parent->schedule(txQueueEvent, txQueue.front().first);
261 } else {
262 // We can't reliably convert in-flight packets from old
263 // checkpoints. In fact, gem5 hasn't been able to load these
264 // packets for at least two years before the format change.
265 warn("Old-style EtherLink serialization format detected, "
266 "in-flight packets may have been dropped.\n");
267 }
268}
269
270} // namespace gem5
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Definition trace.hh:203
#define DPRINTF(x,...)
Definition trace.hh:209
virtual std::string name() const
Definition named.hh:47
Ports are used to interface objects to each other.
Definition port.hh:62
Abstract superclass for simulation objects.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
bool optParamIn(CheckpointIn &cp, const std::string &name, T &param, bool do_warn=true)
This function is used for restoring optional parameters from the checkpoint.
Definition serialize.hh:357
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
#define warn(...)
Definition logging.hh:256
Bitfield< 9 > d
Definition misc_types.hh:64
Bitfield< 0 > p
Bitfield< 0 > pe
Definition misc.hh:619
Bitfield< 51, 12 > base
Definition pagetable.hh:141
void dump()
Dump all statistics data to the registered outputs.
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
std::ostream CheckpointOut
Definition serialize.hh:66
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
Definition types.cc:40
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
Definition types.cc:72
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition types.hh:245
uint64_t Tick
Tick count type.
Definition types.hh:58
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
std::shared_ptr< EthPacketData > EthPacketPtr
Definition etherpkt.hh:90
const std::string & name()
Definition trace.cc:48

Generated on Mon Jan 13 2025 04:28:34 for gem5 by doxygen 1.9.8