Merge m5.eecs.umich.edu:/bk/newmem
[gem5.git] / src / dev / sinic.hh
1 /*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Nathan Binkert
29 */
30
31 #ifndef __DEV_SINIC_HH__
32 #define __DEV_SINIC_HH__
33
34 #include "base/inet.hh"
35 #include "base/statistics.hh"
36 #include "dev/etherint.hh"
37 #include "dev/etherpkt.hh"
38 #include "dev/io_device.hh"
39 #include "dev/pcidev.hh"
40 #include "dev/pktfifo.hh"
41 #include "dev/sinicreg.hh"
42 #include "sim/eventq.hh"
43
44 namespace Sinic {
45
46 class Interface;
47 class Base : public PciDev
48 {
49 protected:
50 bool rxEnable;
51 bool txEnable;
52 Tick clock;
53 inline Tick cycles(int numCycles) const { return numCycles * clock; }
54
55 protected:
56 Tick intrDelay;
57 Tick intrTick;
58 bool cpuIntrEnable;
59 bool cpuPendingIntr;
60 void cpuIntrPost(Tick when);
61 void cpuInterrupt();
62 void cpuIntrClear();
63
64 typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
65 friend void IntrEvent::process();
66 IntrEvent *intrEvent;
67 Interface *interface;
68
69 bool cpuIntrPending() const;
70 void cpuIntrAck() { cpuIntrClear(); }
71
72 /**
73 * Serialization stuff
74 */
75 public:
76 virtual void serialize(std::ostream &os);
77 virtual void unserialize(Checkpoint *cp, const std::string &section);
78
79 /**
80 * Construction/Destruction/Parameters
81 */
82 public:
83 struct Params : public PciDev::Params
84 {
85 Tick clock;
86 Tick intr_delay;
87 };
88
89 Base(Params *p);
90 };
91
92 class Device : public Base
93 {
94 protected:
95 /** Receive State Machine States */
96 enum RxState {
97 rxIdle,
98 rxFifoBlock,
99 rxBeginCopy,
100 rxCopy,
101 rxCopyDone
102 };
103
104 /** Transmit State Machine states */
105 enum TxState {
106 txIdle,
107 txFifoBlock,
108 txBeginCopy,
109 txCopy,
110 txCopyDone
111 };
112
113 /** device register file */
114 struct {
115 uint32_t Config; // 0x00
116 uint32_t Command; // 0x04
117 uint32_t IntrStatus; // 0x08
118 uint32_t IntrMask; // 0x0c
119 uint32_t RxMaxCopy; // 0x10
120 uint32_t TxMaxCopy; // 0x14
121 uint32_t RxMaxIntr; // 0x18
122 uint32_t VirtualCount; // 0x1c
123 uint32_t RxFifoSize; // 0x20
124 uint32_t TxFifoSize; // 0x24
125 uint32_t RxFifoMark; // 0x28
126 uint32_t TxFifoMark; // 0x2c
127 uint64_t RxData; // 0x30
128 uint64_t RxDone; // 0x38
129 uint64_t RxWait; // 0x40
130 uint64_t TxData; // 0x48
131 uint64_t TxDone; // 0x50
132 uint64_t TxWait; // 0x58
133 uint64_t HwAddr; // 0x60
134 } regs;
135
136 struct VirtualReg {
137 uint64_t RxData;
138 uint64_t RxDone;
139 uint64_t TxData;
140 uint64_t TxDone;
141
142 PacketFifo::iterator rxPacket;
143 int rxPacketOffset;
144 int rxPacketBytes;
145 uint64_t rxDoneData;
146
147 Counter rxUnique;
148 Counter txUnique;
149
150 VirtualReg()
151 : RxData(0), RxDone(0), TxData(0), TxDone(0),
152 rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
153 { }
154 };
155 typedef std::vector<VirtualReg> VirtualRegs;
156 typedef std::list<int> VirtualList;
157 Counter rxUnique;
158 Counter txUnique;
159 VirtualRegs virtualRegs;
160 VirtualList rxList;
161 VirtualList rxBusy;
162 int rxActive;
163 VirtualList txList;
164
165 uint8_t &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
166 uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
167 uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
168
169 protected:
170 RxState rxState;
171 PacketFifo rxFifo;
172 PacketFifo::iterator rxFifoPtr;
173 bool rxEmpty;
174 bool rxLow;
175 Addr rxDmaAddr;
176 uint8_t *rxDmaData;
177 int rxDmaLen;
178
179 TxState txState;
180 PacketFifo txFifo;
181 bool txFull;
182 EthPacketPtr txPacket;
183 int txPacketOffset;
184 int txPacketBytes;
185 Addr txDmaAddr;
186 uint8_t *txDmaData;
187 int txDmaLen;
188
189 protected:
190 void reset();
191
192 void rxKick();
193 Tick rxKickTick;
194 typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
195 friend void RxKickEvent::process();
196
197 void txKick();
198 Tick txKickTick;
199 typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
200 friend void TxKickEvent::process();
201
202 /**
203 * Retransmit event
204 */
205 void transmit();
206 void txEventTransmit()
207 {
208 transmit();
209 if (txState == txFifoBlock)
210 txKick();
211 }
212 typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
213 friend void TxEvent::process();
214 TxEvent txEvent;
215
216 void txDump() const;
217 void rxDump() const;
218
219 /**
220 * receive address filter
221 */
222 bool rxFilter(const EthPacketPtr &packet);
223
224 /**
225 * device configuration
226 */
227 void changeConfig(uint32_t newconfig);
228 void command(uint32_t command);
229
230 /**
231 * device ethernet interface
232 */
233 public:
234 bool recvPacket(EthPacketPtr packet);
235 void transferDone();
236 void setInterface(Interface *i) { assert(!interface); interface = i; }
237
238 /**
239 * DMA parameters
240 */
241 protected:
242 void rxDmaDone();
243 friend class EventWrapper<Device, &Device::rxDmaDone>;
244 EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
245
246 void txDmaDone();
247 friend class EventWrapper<Device, &Device::txDmaDone>;
248 EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
249
250 Tick dmaReadDelay;
251 Tick dmaReadFactor;
252 Tick dmaWriteDelay;
253 Tick dmaWriteFactor;
254
255 /**
256 * Interrupt management
257 */
258 protected:
259 void devIntrPost(uint32_t interrupts);
260 void devIntrClear(uint32_t interrupts = Regs::Intr_All);
261 void devIntrChangeMask(uint32_t newmask);
262
263 /**
264 * Memory Interface
265 */
266 public:
267 virtual Tick read(Packet *pkt);
268 virtual Tick write(Packet *pkt);
269 virtual void resume();
270
271 void prepareIO(int cpu, int index);
272 void prepareRead(int cpu, int index);
273 void prepareWrite(int cpu, int index);
274 // Fault iprRead(Addr daddr, int cpu, uint64_t &result);
275
276 /**
277 * Statistics
278 */
279 private:
280 Stats::Scalar<> rxBytes;
281 Stats::Formula rxBandwidth;
282 Stats::Scalar<> rxPackets;
283 Stats::Formula rxPacketRate;
284 Stats::Scalar<> rxIpPackets;
285 Stats::Scalar<> rxTcpPackets;
286 Stats::Scalar<> rxUdpPackets;
287 Stats::Scalar<> rxIpChecksums;
288 Stats::Scalar<> rxTcpChecksums;
289 Stats::Scalar<> rxUdpChecksums;
290
291 Stats::Scalar<> txBytes;
292 Stats::Formula txBandwidth;
293 Stats::Formula totBandwidth;
294 Stats::Formula totPackets;
295 Stats::Formula totBytes;
296 Stats::Formula totPacketRate;
297 Stats::Scalar<> txPackets;
298 Stats::Formula txPacketRate;
299 Stats::Scalar<> txIpPackets;
300 Stats::Scalar<> txTcpPackets;
301 Stats::Scalar<> txUdpPackets;
302 Stats::Scalar<> txIpChecksums;
303 Stats::Scalar<> txTcpChecksums;
304 Stats::Scalar<> txUdpChecksums;
305
306 public:
307 virtual void regStats();
308
309 /**
310 * Serialization stuff
311 */
312 public:
313 virtual void serialize(std::ostream &os);
314 virtual void unserialize(Checkpoint *cp, const std::string &section);
315
316 /**
317 * Construction/Destruction/Parameters
318 */
319 public:
320 struct Params : public Base::Params
321 {
322 Tick tx_delay;
323 Tick rx_delay;
324 bool rx_filter;
325 Net::EthAddr eaddr;
326 uint32_t rx_max_copy;
327 uint32_t tx_max_copy;
328 uint32_t rx_max_intr;
329 uint32_t rx_fifo_size;
330 uint32_t tx_fifo_size;
331 uint32_t rx_fifo_threshold;
332 uint32_t rx_fifo_low_mark;
333 uint32_t tx_fifo_high_mark;
334 uint32_t tx_fifo_threshold;
335 Tick dma_read_delay;
336 Tick dma_read_factor;
337 Tick dma_write_delay;
338 Tick dma_write_factor;
339 bool rx_thread;
340 bool tx_thread;
341 bool rss;
342 uint32_t virtual_count;
343 bool zero_copy;
344 bool delay_copy;
345 bool virtual_addr;
346 };
347
348 protected:
349 const Params *params() const { return (const Params *)_params; }
350
351 public:
352 Device(Params *params);
353 ~Device();
354 };
355
356 /*
357 * Ethernet Interface for an Ethernet Device
358 */
359 class Interface : public EtherInt
360 {
361 private:
362 Device *dev;
363
364 public:
365 Interface(const std::string &name, Device *d)
366 : EtherInt(name), dev(d) { dev->setInterface(this); }
367
368 virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
369 virtual void sendDone() { dev->transferDone(); }
370 };
371
372 /* namespace Sinic */ }
373
374 #endif // __DEV_SINIC_HH__