summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Sandberg <Andreas.Sandberg@arm.com>2012-11-02 11:32:01 -0500
committerAndreas Sandberg <Andreas.Sandberg@arm.com>2012-11-02 11:32:01 -0500
commitdf02047d5a362296bde9d07dba6dba59516fa328 (patch)
treeb52f0bb518cee1c19c49061595defa29f0afcc68
parentc0ab52799ca4ebd0a51363cfedd0658e6d79b842 (diff)
downloadgem5-df02047d5a362296bde9d07dba6dba59516fa328.tar.xz
dev: Fix ethernet device inheritance structure
The Python wrappers and the C++ should have the same object structure. If this is not the case, bad things will happen when the SWIG wrappers cast between an object and any of its base classes. This was not the case for NSGigE and Sinic devices. This patch makes NSGigE and Sinic inherit from the new EtherDevBase class, which in turn inherits from EtherDevice. As a bonus, this removes some duplicated statistics from the Sinic device.
-rw-r--r--src/dev/Ethernet.py2
-rw-r--r--src/dev/etherdevice.hh28
-rw-r--r--src/dev/ns_gige.cc2
-rw-r--r--src/dev/ns_gige.hh7
-rw-r--r--src/dev/sinic.cc170
-rw-r--r--src/dev/sinic.hh29
6 files changed, 42 insertions, 196 deletions
diff --git a/src/dev/Ethernet.py b/src/dev/Ethernet.py
index 57d867fbe..a8b5555d9 100644
--- a/src/dev/Ethernet.py
+++ b/src/dev/Ethernet.py
@@ -132,6 +132,8 @@ class IGbE_igb(IGbE):
class EtherDevBase(EtherDevice):
type = 'EtherDevBase'
abstract = True
+ cxx_header = "dev/etherdevice.hh"
+
hardware_address = Param.EthernetAddr(NextEthernetAddr,
"Ethernet Hardware Address")
diff --git a/src/dev/etherdevice.hh b/src/dev/etherdevice.hh
index 5d86275b4..81e5535b0 100644
--- a/src/dev/etherdevice.hh
+++ b/src/dev/etherdevice.hh
@@ -39,6 +39,7 @@
#include "base/statistics.hh"
#include "dev/pcidev.hh"
#include "params/EtherDevice.hh"
+#include "params/EtherDevBase.hh"
#include "sim/sim_object.hh"
class EtherInt;
@@ -120,4 +121,31 @@ class EtherDevice : public PciDev
Stats::Scalar droppedPackets;
};
+/**
+ * Dummy class to keep the Python class hierarchy in sync with the C++
+ * object hierarchy.
+ *
+ * The Python object hierarchy includes the EtherDevBase class which
+ * is used by some ethernet devices as a way to share common
+ * configuration information in the generated param structs. Since the
+ * Python hierarchy is used to generate a SWIG interface for all C++
+ * SimObjects, we need to reflect this in the C++ object hierarchy. If
+ * we don't, SWIG might end up doing 'bad things' when it down casts
+ * ethernet objects to their base class(es).
+ */
+class EtherDevBase : public EtherDevice
+{
+ public:
+ EtherDevBase(const EtherDevBaseParams *params)
+ : EtherDevice(params)
+ {}
+
+ const EtherDevBaseParams *
+ params() const
+ {
+ return dynamic_cast<const EtherDevBaseParams *>(_params);
+ }
+
+};
+
#endif //__DEV_ETHERDEVICE_HH__
diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc
index 583cdb140..0af9fbfc5 100644
--- a/src/dev/ns_gige.cc
+++ b/src/dev/ns_gige.cc
@@ -95,7 +95,7 @@ using namespace TheISA;
// NSGigE PCI Device
//
NSGigE::NSGigE(Params *p)
- : EtherDevice(p), ioEnable(false),
+ : EtherDevBase(p), ioEnable(false),
txFifo(p->tx_fifo_size), rxFifo(p->rx_fifo_size),
txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL),
txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
diff --git a/src/dev/ns_gige.hh b/src/dev/ns_gige.hh
index 8032c0623..f4d0171d6 100644
--- a/src/dev/ns_gige.hh
+++ b/src/dev/ns_gige.hh
@@ -118,7 +118,7 @@ class Packet;
/**
* NS DP83820 Ethernet device model
*/
-class NSGigE : public EtherDevice
+class NSGigE : public EtherDevBase
{
public:
/** Transmit State Machine states */
@@ -346,7 +346,10 @@ class NSGigE : public EtherDevice
public:
typedef NSGigEParams Params;
- const Params *params() const { return (const Params *)_params; }
+ const Params *params() const {
+ return dynamic_cast<const Params *>(_params);
+ }
+
NSGigE(Params *params);
~NSGigE();
diff --git a/src/dev/sinic.cc b/src/dev/sinic.cc
index cdfa844d9..2d109cbbb 100644
--- a/src/dev/sinic.cc
+++ b/src/dev/sinic.cc
@@ -78,7 +78,7 @@ const char *TxStateStrings[] =
// Sinic PCI Device
//
Base::Base(const Params *p)
- : PciDev(p), rxEnable(false), txEnable(false),
+ : EtherDevBase(p), rxEnable(false), txEnable(false),
intrDelay(p->intr_delay), intrTick(0), cpuIntrEnable(false),
cpuPendingIntr(false), intrEvent(0), interface(NULL)
{
@@ -104,171 +104,7 @@ Device::~Device()
void
Device::regStats()
{
- rxBytes
- .name(name() + ".rxBytes")
- .desc("Bytes Received")
- .prereq(rxBytes)
- ;
-
- rxBandwidth
- .name(name() + ".rxBandwidth")
- .desc("Receive Bandwidth (bits/s)")
- .precision(0)
- .prereq(rxBytes)
- ;
-
- rxPackets
- .name(name() + ".rxPackets")
- .desc("Number of Packets Received")
- .prereq(rxBytes)
- ;
-
- rxPacketRate
- .name(name() + ".rxPPS")
- .desc("Packet Reception Rate (packets/s)")
- .precision(0)
- .prereq(rxBytes)
- ;
-
- rxIpPackets
- .name(name() + ".rxIpPackets")
- .desc("Number of IP Packets Received")
- .prereq(rxBytes)
- ;
-
- rxTcpPackets
- .name(name() + ".rxTcpPackets")
- .desc("Number of Packets Received")
- .prereq(rxBytes)
- ;
-
- rxUdpPackets
- .name(name() + ".rxUdpPackets")
- .desc("Number of UDP Packets Received")
- .prereq(rxBytes)
- ;
-
- rxIpChecksums
- .name(name() + ".rxIpChecksums")
- .desc("Number of rx IP Checksums done by device")
- .precision(0)
- .prereq(rxBytes)
- ;
-
- rxTcpChecksums
- .name(name() + ".rxTcpChecksums")
- .desc("Number of rx TCP Checksums done by device")
- .precision(0)
- .prereq(rxBytes)
- ;
-
- rxUdpChecksums
- .name(name() + ".rxUdpChecksums")
- .desc("Number of rx UDP Checksums done by device")
- .precision(0)
- .prereq(rxBytes)
- ;
-
- totBandwidth
- .name(name() + ".totBandwidth")
- .desc("Total Bandwidth (bits/s)")
- .precision(0)
- .prereq(totBytes)
- ;
-
- totPackets
- .name(name() + ".totPackets")
- .desc("Total Packets")
- .precision(0)
- .prereq(totBytes)
- ;
-
- totBytes
- .name(name() + ".totBytes")
- .desc("Total Bytes")
- .precision(0)
- .prereq(totBytes)
- ;
-
- totPacketRate
- .name(name() + ".totPPS")
- .desc("Total Tranmission Rate (packets/s)")
- .precision(0)
- .prereq(totBytes)
- ;
-
- txBytes
- .name(name() + ".txBytes")
- .desc("Bytes Transmitted")
- .prereq(txBytes)
- ;
-
- txBandwidth
- .name(name() + ".txBandwidth")
- .desc("Transmit Bandwidth (bits/s)")
- .precision(0)
- .prereq(txBytes)
- ;
-
- txPackets
- .name(name() + ".txPackets")
- .desc("Number of Packets Transmitted")
- .prereq(txBytes)
- ;
-
- txPacketRate
- .name(name() + ".txPPS")
- .desc("Packet Tranmission Rate (packets/s)")
- .precision(0)
- .prereq(txBytes)
- ;
-
- txIpPackets
- .name(name() + ".txIpPackets")
- .desc("Number of IP Packets Transmitted")
- .prereq(txBytes)
- ;
-
- txTcpPackets
- .name(name() + ".txTcpPackets")
- .desc("Number of TCP Packets Transmitted")
- .prereq(txBytes)
- ;
-
- txUdpPackets
- .name(name() + ".txUdpPackets")
- .desc("Number of Packets Transmitted")
- .prereq(txBytes)
- ;
-
- txIpChecksums
- .name(name() + ".txIpChecksums")
- .desc("Number of tx IP Checksums done by device")
- .precision(0)
- .prereq(txBytes)
- ;
-
- txTcpChecksums
- .name(name() + ".txTcpChecksums")
- .desc("Number of tx TCP Checksums done by device")
- .precision(0)
- .prereq(txBytes)
- ;
-
- txUdpChecksums
- .name(name() + ".txUdpChecksums")
- .desc("Number of tx UDP Checksums done by device")
- .precision(0)
- .prereq(txBytes)
- ;
-
- txBandwidth = txBytes * Stats::constant(8) / simSeconds;
- rxBandwidth = rxBytes * Stats::constant(8) / simSeconds;
- totBandwidth = txBandwidth + rxBandwidth;
- totBytes = txBytes + rxBytes;
- totPackets = txPackets + rxPackets;
- txPacketRate = txPackets / simSeconds;
- rxPacketRate = rxPackets / simSeconds;
+ Base::regStats();
_maxVnicDistance = 0;
@@ -297,6 +133,8 @@ Device::regStats()
void
Device::resetStats()
{
+ Base::resetStats();
+
_maxVnicDistance = 0;
}
diff --git a/src/dev/sinic.hh b/src/dev/sinic.hh
index 5532650c3..8189ce39a 100644
--- a/src/dev/sinic.hh
+++ b/src/dev/sinic.hh
@@ -33,6 +33,7 @@
#include "base/inet.hh"
#include "base/statistics.hh"
+#include "dev/etherdevice.hh"
#include "dev/etherint.hh"
#include "dev/etherpkt.hh"
#include "dev/io_device.hh"
@@ -45,7 +46,7 @@
namespace Sinic {
class Interface;
-class Base : public PciDev
+class Base : public EtherDevBase
{
protected:
bool rxEnable;
@@ -281,32 +282,6 @@ class Device : public Base
* Statistics
*/
private:
- Stats::Scalar rxBytes;
- Stats::Formula rxBandwidth;
- Stats::Scalar rxPackets;
- Stats::Formula rxPacketRate;
- Stats::Scalar rxIpPackets;
- Stats::Scalar rxTcpPackets;
- Stats::Scalar rxUdpPackets;
- Stats::Scalar rxIpChecksums;
- Stats::Scalar rxTcpChecksums;
- Stats::Scalar rxUdpChecksums;
-
- Stats::Scalar txBytes;
- Stats::Formula txBandwidth;
- Stats::Formula totBandwidth;
- Stats::Formula totPackets;
- Stats::Formula totBytes;
- Stats::Formula totPacketRate;
- Stats::Scalar txPackets;
- Stats::Formula txPacketRate;
- Stats::Scalar txIpPackets;
- Stats::Scalar txTcpPackets;
- Stats::Scalar txUdpPackets;
- Stats::Scalar txIpChecksums;
- Stats::Scalar txTcpChecksums;
- Stats::Scalar txUdpChecksums;
-
Stats::Scalar totalVnicDistance;
Stats::Scalar numVnicDistance;
Stats::Scalar maxVnicDistance;