summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-08-18 19:41:08 -0700
committerGabe Black <gblack@eecs.umich.edu>2007-08-18 19:41:08 -0700
commita874cb40ab9f22612b0609cbac2c739daebacbd5 (patch)
tree551e5aadc93be0ba3013e2b33272d08c78da01f9
parent4bce50340f8fc1e1e0361cef1971dd127125d5a5 (diff)
parent464a51e29e858d6dc38847120868b36e97c8bb6d (diff)
downloadgem5-a874cb40ab9f22612b0609cbac2c739daebacbd5.tar.xz
Merge with head.
--HG-- extra : convert_revision : 6ce77b5bd4f43ddecd51ea8c66759e4b70d4ad82
-rw-r--r--configs/common/FSConfig.py10
-rw-r--r--src/dev/Ethernet.py90
-rw-r--r--src/dev/Ide.py24
-rw-r--r--src/dev/Pci.py35
-rw-r--r--src/dev/etherbus.cc17
-rw-r--r--src/dev/etherbus.hh15
-rw-r--r--src/dev/etherdevice.hh69
-rw-r--r--src/dev/etherint.hh11
-rw-r--r--src/dev/etherlink.cc40
-rw-r--r--src/dev/etherlink.hh18
-rw-r--r--src/dev/etherobject.hh67
-rw-r--r--src/dev/etherpkt.hh12
-rw-r--r--src/dev/ethertap.cc37
-rw-r--r--src/dev/ethertap.hh33
-rw-r--r--src/dev/i8254xGBe.cc32
-rw-r--r--src/dev/i8254xGBe.hh11
-rw-r--r--src/dev/ns_gige.cc30
-rw-r--r--src/dev/ns_gige.hh11
-rw-r--r--src/dev/pcidev.cc109
-rw-r--r--src/dev/pcidev.hh38
-rw-r--r--src/dev/sinic.cc33
-rw-r--r--src/dev/sinic.hh10
-rw-r--r--src/python/swig/pyobject.cc53
-rw-r--r--util/style.py3
24 files changed, 506 insertions, 302 deletions
diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py
index e2d6b710b..2ab214dc5 100644
--- a/configs/common/FSConfig.py
+++ b/configs/common/FSConfig.py
@@ -40,9 +40,7 @@ class CowIdeDisk(IdeDisk):
def makeLinuxAlphaSystem(mem_mode, mdesc = None):
class BaseTsunami(Tsunami):
- ethernet = NSGigE(configdata=NSGigEPciData(),
- pci_bus=0, pci_dev=1, pci_func=0)
- etherint = NSGigEInt(device=Parent.ethernet)
+ ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0)
ide = IdeController(disks=[Parent.disk0, Parent.disk2],
pci_func=0, pci_dev=0, pci_bus=0)
@@ -125,8 +123,10 @@ def makeDualRoot(testSystem, driveSystem, dumpfile):
self = Root()
self.testsys = testSystem
self.drivesys = driveSystem
- self.etherlink = EtherLink(int1 = Parent.testsys.tsunami.etherint[0],
- int2 = Parent.drivesys.tsunami.etherint[0])
+ self.etherlink = EtherLink()
+ self.etherlink.int0 = Parent.testsys.tsunami.ethernet.interface
+ self.etherlink.int1 = Parent.drivesys.tsunami.ethernet.interface
+
if dumpfile:
self.etherdump = EtherDump(file=dumpfile)
self.etherlink.dump = Parent.etherdump
diff --git a/src/dev/Ethernet.py b/src/dev/Ethernet.py
index c978470ca..2beb0d537 100644
--- a/src/dev/Ethernet.py
+++ b/src/dev/Ethernet.py
@@ -29,29 +29,28 @@
from m5.SimObject import SimObject
from m5.params import *
from m5.proxy import *
-from Pci import PciDevice, PciConfigData
+from Pci import PciDevice
-class EtherInt(SimObject):
- type = 'EtherInt'
+class EtherObject(SimObject):
+ type = 'EtherObject'
abstract = True
- peer = Param.EtherInt(NULL, "peer interface")
-class EtherLink(SimObject):
+class EtherLink(EtherObject):
type = 'EtherLink'
- int1 = Param.EtherInt("interface 1")
- int2 = Param.EtherInt("interface 2")
+ int0 = Port("interface 0")
+ int1 = Port("interface 1")
delay = Param.Latency('0us', "packet transmit delay")
delay_var = Param.Latency('0ns', "packet transmit delay variability")
speed = Param.NetworkBandwidth('1Gbps', "link speed")
dump = Param.EtherDump(NULL, "dump object")
-class EtherBus(SimObject):
+class EtherBus(EtherObject):
type = 'EtherBus'
loopback = Param.Bool(True, "send packet back to the sending interface")
dump = Param.EtherDump(NULL, "dump object")
speed = Param.NetworkBandwidth('100Mbps', "bus speed in bits per second")
-class EtherTap(EtherInt):
+class EtherTap(EtherObject):
type = 'EtherTap'
bufsz = Param.Int(10000, "tap buffer size")
dump = Param.EtherDump(NULL, "dump object")
@@ -62,7 +61,12 @@ class EtherDump(SimObject):
file = Param.String("dump file")
maxlen = Param.Int(96, "max portion of packet data to dump")
-class IGbE(PciDevice):
+class EtherDevice(PciDevice):
+ type = 'EtherDevice'
+ abstract = True
+ interface = Port("Ethernet Interrface")
+
+class IGbE(EtherDevice):
type = 'IGbE'
hardware_address = Param.EthernetAddr(NextEthernetAddr,
"Ethernet Hardware Address")
@@ -75,8 +79,6 @@ class IGbE(PciDevice):
tx_desc_cache_size = Param.Int(64,
"Number of enteries in the rx descriptor cache")
clock = Param.Clock('500MHz', "Clock speed of the device")
-
-class IGbEPciData(PciConfigData):
VendorID = 0x8086
DeviceID = 0x1075
SubsystemID = 0x1008
@@ -97,11 +99,7 @@ class IGbEPciData(PciConfigData):
InterruptPin = 0x01
BAR0Size = '128kB'
-class IGbEInt(EtherInt):
- type = 'IGbEInt'
- device = Param.IGbE("Ethernet device of this interface")
-
-class EtherDevBase(PciDevice):
+class EtherDevBase(EtherDevice):
type = 'EtherDevBase'
abstract = True
hardware_address = Param.EthernetAddr(NextEthernetAddr,
@@ -125,7 +123,13 @@ class EtherDevBase(PciDevice):
tx_thread = Param.Bool(False, "dedicated kernel threads for receive")
rss = Param.Bool(False, "Receive Side Scaling")
-class NSGigEPciData(PciConfigData):
+class NSGigE(EtherDevBase):
+ type = 'NSGigE'
+
+ dma_data_free = Param.Bool(False, "DMA of Data is free")
+ dma_desc_free = Param.Bool(False, "DMA of Descriptors is free")
+ dma_no_allocate = Param.Bool(True, "Should we allocate cache on read")
+
VendorID = 0x100B
DeviceID = 0x0022
Status = 0x0290
@@ -145,21 +149,25 @@ class NSGigEPciData(PciConfigData):
BAR0Size = '256B'
BAR1Size = '4kB'
-class NSGigE(EtherDevBase):
- type = 'NSGigE'
-
- dma_data_free = Param.Bool(False, "DMA of Data is free")
- dma_desc_free = Param.Bool(False, "DMA of Descriptors is free")
- dma_no_allocate = Param.Bool(True, "Should we allocate cache on read")
- configdata = NSGigEPciData()
+class Sinic(EtherDevBase):
+ type = 'Sinic'
+ cxx_namespace = 'Sinic'
+ cxx_class = 'Device'
-class NSGigEInt(EtherInt):
- type = 'NSGigEInt'
- device = Param.NSGigE("Ethernet device of this interface")
+ rx_max_copy = Param.MemorySize('1514B', "rx max copy")
+ tx_max_copy = Param.MemorySize('16kB', "tx max copy")
+ rx_max_intr = Param.UInt32(10, "max rx packets per interrupt")
+ rx_fifo_threshold = Param.MemorySize('384kB', "rx fifo high threshold")
+ rx_fifo_low_mark = Param.MemorySize('128kB', "rx fifo low threshold")
+ tx_fifo_high_mark = Param.MemorySize('384kB', "tx fifo high threshold")
+ tx_fifo_threshold = Param.MemorySize('128kB', "tx fifo low threshold")
+ virtual_count = Param.UInt32(1, "Virtualized SINIC")
+ zero_copy = Param.Bool(False, "Zero copy receive")
+ delay_copy = Param.Bool(False, "Delayed copy transmit")
+ virtual_addr = Param.Bool(False, "Virtual addressing")
-class SinicPciData(PciConfigData):
VendorID = 0x1291
DeviceID = 0x1293
Status = 0x0290
@@ -178,28 +186,4 @@ class SinicPciData(PciConfigData):
InterruptPin = 0x01
BAR0Size = '64kB'
-class Sinic(EtherDevBase):
- type = 'Sinic'
- cxx_namespace = 'Sinic'
- cxx_class = 'Device'
-
- rx_max_copy = Param.MemorySize('1514B', "rx max copy")
- tx_max_copy = Param.MemorySize('16kB', "tx max copy")
- rx_max_intr = Param.UInt32(10, "max rx packets per interrupt")
- rx_fifo_threshold = Param.MemorySize('384kB', "rx fifo high threshold")
- rx_fifo_low_mark = Param.MemorySize('128kB', "rx fifo low threshold")
- tx_fifo_high_mark = Param.MemorySize('384kB', "tx fifo high threshold")
- tx_fifo_threshold = Param.MemorySize('128kB', "tx fifo low threshold")
- virtual_count = Param.UInt32(1, "Virtualized SINIC")
- zero_copy = Param.Bool(False, "Zero copy receive")
- delay_copy = Param.Bool(False, "Delayed copy transmit")
- virtual_addr = Param.Bool(False, "Virtual addressing")
-
- configdata = SinicPciData()
-
-class SinicInt(EtherInt):
- type = 'SinicInt'
- cxx_namespace = 'Sinic'
- cxx_class = 'Interface'
- device = Param.Sinic("Ethernet device of this interface")
diff --git a/src/dev/Ide.py b/src/dev/Ide.py
index 6bbaad00e..a396c9690 100644
--- a/src/dev/Ide.py
+++ b/src/dev/Ide.py
@@ -28,11 +28,20 @@
from m5.SimObject import SimObject
from m5.params import *
-from Pci import PciDevice, PciConfigData
+from Pci import PciDevice
class IdeID(Enum): vals = ['master', 'slave']
-class IdeControllerPciData(PciConfigData):
+class IdeDisk(SimObject):
+ type = 'IdeDisk'
+ delay = Param.Latency('1us', "Fixed disk delay in microseconds")
+ driveID = Param.IdeID('master', "Drive ID")
+ image = Param.DiskImage("Disk image")
+
+class IdeController(PciDevice):
+ type = 'IdeController'
+ disks = VectorParam.IdeDisk("IDE disks attached to this controller")
+
VendorID = 0x8086
DeviceID = 0x7111
Command = 0x0
@@ -55,14 +64,3 @@ class IdeControllerPciData(PciConfigData):
BAR3Size = '4B'
BAR4Size = '16B'
-class IdeDisk(SimObject):
- type = 'IdeDisk'
- delay = Param.Latency('1us', "Fixed disk delay in microseconds")
- driveID = Param.IdeID('master', "Drive ID")
- image = Param.DiskImage("Disk image")
-
-class IdeController(PciDevice):
- type = 'IdeController'
- disks = VectorParam.IdeDisk("IDE disks attached to this controller")
-
- configdata =IdeControllerPciData()
diff --git a/src/dev/Pci.py b/src/dev/Pci.py
index b2c013f41..b50e1b15c 100644
--- a/src/dev/Pci.py
+++ b/src/dev/Pci.py
@@ -31,8 +31,23 @@ from m5.params import *
from m5.proxy import *
from Device import BasicPioDevice, DmaDevice, PioDevice
-class PciConfigData(SimObject):
- type = 'PciConfigData'
+class PciConfigAll(PioDevice):
+ type = 'PciConfigAll'
+ pio_latency = Param.Tick(1, "Programmed IO latency in simticks")
+ bus = Param.UInt8(0x00, "PCI bus to act as config space for")
+ size = Param.MemorySize32('16MB', "Size of config space")
+
+
+class PciDevice(DmaDevice):
+ type = 'PciDevice'
+ abstract = True
+ config = Port(Self.pio.peerObj.port, "PCI configuration space port")
+ pci_bus = Param.Int("PCI bus")
+ pci_dev = Param.Int("PCI device number")
+ pci_func = Param.Int("PCI function code")
+ pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
+ config_latency = Param.Latency('20ns', "Config read or write latency")
+
VendorID = Param.UInt16("Vendor ID")
DeviceID = Param.UInt16("Device ID")
Command = Param.UInt16(0, "Command")
@@ -68,20 +83,4 @@ class PciConfigData(SimObject):
MaximumLatency = Param.UInt8(0x00, "Maximum Latency")
MinimumGrant = Param.UInt8(0x00, "Minimum Grant")
-class PciConfigAll(PioDevice):
- type = 'PciConfigAll'
- pio_latency = Param.Tick(1, "Programmed IO latency in simticks")
- bus = Param.UInt8(0x00, "PCI bus to act as config space for")
- size = Param.MemorySize32('16MB', "Size of config space")
-
-class PciDevice(DmaDevice):
- type = 'PciDevice'
- abstract = True
- config = Port(Self.pio.peerObj.port, "PCI configuration space port")
- pci_bus = Param.Int("PCI bus")
- pci_dev = Param.Int("PCI device number")
- pci_func = Param.Int("PCI function code")
- pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
- configdata = Param.PciConfigData(Parent.any, "PCI Config data")
- config_latency = Param.Latency('20ns', "Config read or write latency")
diff --git a/src/dev/etherbus.cc b/src/dev/etherbus.cc
index 3e59229ad..2316bfed9 100644
--- a/src/dev/etherbus.cc
+++ b/src/dev/etherbus.cc
@@ -47,10 +47,9 @@
using namespace std;
-EtherBus::EtherBus(const string &name, double speed, bool loop,
- EtherDump *packet_dump)
- : SimObject(name), ticksPerByte(speed), loopback(loop),
- event(&mainEventQueue, this), sender(0), dump(packet_dump)
+EtherBus::EtherBus(const Params *p)
+ : EtherObject(p), ticksPerByte(p->speed), loopback(p->loopback),
+ event(&mainEventQueue, this), sender(0), dump(p->dump)
{
}
@@ -78,9 +77,11 @@ EtherBus::txDone()
packet = 0;
}
-void
-EtherBus::reg(EtherInt *dev)
-{ devlist.push_back(dev); }
+EtherInt*
+EtherBus::getEthPort(const std::string &if_name, int idx)
+{
+ panic("Etherbus doesn't work\n");
+}
bool
EtherBus::send(EtherInt *sndr, EthPacketPtr &pkt)
@@ -106,5 +107,5 @@ EtherBus::send(EtherInt *sndr, EthPacketPtr &pkt)
EtherBus *
EtherBusParams::create()
{
- return new EtherBus(name, speed, loopback, dump);
+ return new EtherBus(this);
}
diff --git a/src/dev/etherbus.hh b/src/dev/etherbus.hh
index 2ff1d0a5e..a3a7f0606 100644
--- a/src/dev/etherbus.hh
+++ b/src/dev/etherbus.hh
@@ -37,11 +37,13 @@
#include "sim/eventq.hh"
#include "dev/etherpkt.hh"
+#include "dev/etherobject.hh"
+#include "params/EtherBus.hh"
#include "sim/sim_object.hh"
class EtherDump;
class EtherInt;
-class EtherBus : public SimObject
+class EtherBus : public EtherObject
{
protected:
typedef std::list<EtherInt *> devlist_t;
@@ -68,14 +70,21 @@ class EtherBus : public SimObject
EtherDump *dump;
public:
- EtherBus(const std::string &name, double speed, bool loopback,
- EtherDump *dump);
+ typedef EtherBusParams Params;
+ EtherBus(const Params *p);
virtual ~EtherBus() {}
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
void txDone();
void reg(EtherInt *dev);
bool busy() const { return (bool)packet; }
bool send(EtherInt *sender, EthPacketPtr &packet);
+ virtual EtherInt *getEthPort(const std::string &if_name, int idx);
};
#endif // __ETHERBUS_H__
diff --git a/src/dev/etherdevice.hh b/src/dev/etherdevice.hh
new file mode 100644
index 000000000..a0df0d741
--- /dev/null
+++ b/src/dev/etherdevice.hh
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2007 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+/**
+ * @file
+ * Base Ethernet Device declaration.
+ */
+
+#ifndef __DEV_ETHERDEVICE_HH__
+#define __DEV_ETHERDEVICE_HH__
+
+#include "dev/pcidev.hh"
+#include "params/EtherDevice.hh"
+#include "sim/sim_object.hh"
+
+class EtherInt;
+
+/**
+ * The base EtherObject class, allows for an accesor function to a
+ * simobj that returns the Port.
+ */
+class EtherDevice : public PciDev
+{
+ public:
+ typedef EtherDeviceParams Params;
+ EtherDevice(const Params *params)
+ : PciDev(params)
+ {}
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ public:
+ /** Additional function to return the Port of a memory object. */
+ virtual EtherInt *getEthPort(const std::string &if_name, int idx = -1) = 0;
+
+};
+
+#endif //__DEV_ETHERDEVICE_HH__
diff --git a/src/dev/etherint.hh b/src/dev/etherint.hh
index 430f45d66..98b820dbf 100644
--- a/src/dev/etherint.hh
+++ b/src/dev/etherint.hh
@@ -39,23 +39,28 @@
#include <string>
#include "dev/etherpkt.hh"
-#include "sim/sim_object.hh"
/*
* Class representing the actual interface between two ethernet
* components. These components are intended to attach to another
* ethernet interface on one side and whatever device on the other.
*/
-class EtherInt : public SimObject
+class EtherInt
{
protected:
+ mutable std::string portName;
EtherInt *peer;
public:
- EtherInt(const std::string &name) : SimObject(name), peer(NULL) {}
+ EtherInt(const std::string &name)
+ : portName(name), peer(NULL) {}
virtual ~EtherInt() {}
+ /** Return port name (for DPRINTF). */
+ const std::string &name() const { return portName; }
+
void setPeer(EtherInt *p);
+ EtherInt* getPeer() { return peer; }
void recvDone() { peer->sendDone(); }
virtual void sendDone() = 0;
diff --git a/src/dev/etherlink.cc b/src/dev/etherlink.cc
index 8c54da678..baa4fb741 100644
--- a/src/dev/etherlink.cc
+++ b/src/dev/etherlink.cc
@@ -51,22 +51,19 @@
using namespace std;
-EtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1,
- double rate, Tick delay, Tick delayVar, EtherDump *dump)
- : SimObject(name)
+EtherLink::EtherLink(const Params *p)
+ : EtherObject(p)
{
- link[0] = new Link(name + ".link0", this, 0, rate, delay, delayVar, dump);
- link[1] = new Link(name + ".link1", this, 1, rate, delay, delayVar, dump);
+ link[0] = new Link(name() + ".link0", this, 0, params()->speed,
+ params()->delay, params()->delay_var, params()->dump);
+ link[1] = new Link(name() + ".link1", this, 1, params()->speed,
+ params()->delay, params()->delay_var, params()->dump);
- interface[0] = new Interface(name + ".int0", link[0], link[1]);
- interface[1] = new Interface(name + ".int1", link[1], link[0]);
-
- interface[0]->setPeer(peer0);
- peer0->setPeer(interface[0]);
- interface[1]->setPeer(peer1);
- peer1->setPeer(interface[1]);
+ interface[0] = new Interface(name() + ".int0", link[0], link[1]);
+ interface[1] = new Interface(name() + ".int1", link[1], link[0]);
}
+
EtherLink::~EtherLink()
{
delete link[0];
@@ -76,6 +73,23 @@ EtherLink::~EtherLink()
delete interface[1];
}
+EtherInt*
+EtherLink::getEthPort(const std::string &if_name, int idx)
+{
+ Interface *i;
+ if (if_name == "int0")
+ i = interface[0];
+ else if (if_name == "int1")
+ i = interface[1];
+ else
+ return NULL;
+ if (i->getPeer())
+ panic("interface already connected to\n");
+
+ return i;
+}
+
+
EtherLink::Interface::Interface(const string &name, Link *tx, Link *rx)
: EtherInt(name), txlink(tx)
{
@@ -275,5 +289,5 @@ REGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent)
EtherLink *
EtherLinkParams::create()
{
- return new EtherLink(name, int1, int2, speed, delay, delay_var, dump);
+ return new EtherLink(this);
}
diff --git a/src/dev/etherlink.hh b/src/dev/etherlink.hh
index a16d6d799..52092dbf4 100644
--- a/src/dev/etherlink.hh
+++ b/src/dev/etherlink.hh
@@ -35,8 +35,10 @@
#ifndef __DEV_ETHERLINK_HH__
#define __DEV_ETHERLINK_HH__
+#include "dev/etherobject.hh"
#include "dev/etherint.hh"
#include "dev/etherpkt.hh"
+#include "params/EtherLink.hh"
#include "sim/eventq.hh"
#include "sim/host.hh"
#include "sim/sim_object.hh"
@@ -46,7 +48,7 @@ class Checkpoint;
/*
* Model for a fixed bandwidth full duplex ethernet link
*/
-class EtherLink : public SimObject
+class EtherLink : public EtherObject
{
protected:
class Interface;
@@ -118,13 +120,21 @@ class EtherLink : public SimObject
};
Link *link[2];
- EtherInt *interface[2];
+ Interface *interface[2];
public:
- EtherLink(const std::string &name, EtherInt *peer0, EtherInt *peer1,
- double rate, Tick delay, Tick delayVar, EtherDump *dump);
+ typedef EtherLinkParams Params;
+ EtherLink(const Params *p);
virtual ~EtherLink();
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ virtual EtherInt *getEthPort(const std::string &if_name, int idx);
+
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
diff --git a/src/dev/etherobject.hh b/src/dev/etherobject.hh
new file mode 100644
index 000000000..02a30abac
--- /dev/null
+++ b/src/dev/etherobject.hh
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+/**
+ * @file
+ * Base Ethernet Object declaration.
+ */
+
+#ifndef __DEV_ETHEROBJECT_HH__
+#define __DEV_ETHEROBJECT_HH__
+
+#include "params/EtherObject.hh"
+#include "sim/sim_object.hh"
+
+class EtherInt;
+
+/**
+ * The base EtherObject class, allows for an accesor function to a
+ * simobj that returns the Port.
+ */
+class EtherObject : public SimObject
+{
+ public:
+ typedef EtherObjectParams Params;
+ EtherObject(const Params *params)
+ : SimObject(params) {}
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ public:
+ /** Additional function to return the Port of a memory object. */
+ virtual EtherInt *getEthPort(const std::string &if_name, int idx = -1) = 0;
+
+};
+
+#endif //__MEM_MEM_OBJECT_HH__
diff --git a/src/dev/etherpkt.hh b/src/dev/etherpkt.hh
index 80c7baff7..db2e0d6b5 100644
--- a/src/dev/etherpkt.hh
+++ b/src/dev/etherpkt.hh
@@ -69,11 +69,17 @@ class EthPacketData : public RefCounted
int slack;
public:
- EthPacketData() : data(NULL), length(0), slack(0) { }
+ EthPacketData() : data(NULL), length(0), slack(0)
+ { }
+
explicit EthPacketData(size_t size)
- : data(new uint8_t[size]), length(0), slack(0) { }
+ : data(new uint8_t[size]), length(0), slack(0)
+ { }
+
EthPacketData(std::auto_ptr<uint8_t> d, int l, int s = 0)
- : data(d.release()), length(l), slack(s) { }
+ : data(d.release()), length(l), slack(s)
+ { }
+
~EthPacketData() { if (data) delete [] data; }
public:
diff --git a/src/dev/ethertap.cc b/src/dev/ethertap.cc
index 0b6ab97fc..81b84d179 100644
--- a/src/dev/ethertap.cc
+++ b/src/dev/ethertap.cc
@@ -50,7 +50,6 @@
#include "dev/etherint.hh"
#include "dev/etherpkt.hh"
#include "dev/ethertap.hh"
-#include "params/EtherTap.hh"
using namespace std;
@@ -127,13 +126,14 @@ class TapEvent : public PollEvent
virtual void process(int revent) { tap->process(revent); }
};
-EtherTap::EtherTap(const string &name, EtherDump *d, int port, int bufsz)
- : EtherInt(name), event(NULL), socket(-1), buflen(bufsz), dump(d),
- txEvent(this)
+EtherTap::EtherTap(const Params *p)
+ : EtherObject(p), event(NULL), socket(-1), buflen(p->bufsz), dump(p->dump),
+ interface(NULL), txEvent(this)
{
buffer = new char[buflen];
- listener = new TapListener(this, port);
+ listener = new TapListener(this, p->port);
listener->listen();
+ interface = new EtherTapInt(name() + ".interface", this);
}
EtherTap::~EtherTap()
@@ -182,7 +182,7 @@ EtherTap::recvPacket(EthPacketPtr packet)
write(socket, &len, sizeof(len));
write(socket, packet->data, packet->length);
- recvDone();
+ interface->recvDone();
return true;
}
@@ -235,7 +235,7 @@ EtherTap::process(int revent)
DPRINTF(Ethernet, "EtherTap input len=%d\n", packet->length);
DDUMP(EthernetData, packet->data, packet->length);
- if (!sendPacket(packet)) {
+ if (!interface->sendPacket(packet)) {
DPRINTF(Ethernet, "bus busy...buffer for retransmission\n");
packetBuffer.push(packet);
if (!txEvent.scheduled())
@@ -253,7 +253,7 @@ EtherTap::retransmit()
return;
EthPacketPtr packet = packetBuffer.front();
- if (sendPacket(packet)) {
+ if (interface->sendPacket(packet)) {
if (dump)
dump->dump(packet);
DPRINTF(Ethernet, "EtherTap retransmit\n");
@@ -265,6 +265,18 @@ EtherTap::retransmit()
txEvent.schedule(curTick + retryTime);
}
+EtherInt*
+EtherTap::getEthPort(const std::string &if_name, int idx)
+{
+ if (if_name == "tap") {
+ if (interface->getPeer())
+ panic("Interface already connected to\n");
+ return interface;
+ }
+ return NULL;
+}
+
+
//=====================================================================
void
@@ -316,12 +328,5 @@ EtherTap::unserialize(Checkpoint *cp, const std::string &section)
EtherTap *
EtherTapParams::create()
{
- EtherTap *tap = new EtherTap(name, dump, port, bufsz);
-
- if (peer) {
- tap->setPeer(peer);
- peer->setPeer(tap);
- }
-
- return tap;
+ return new EtherTap(this);
}
diff --git a/src/dev/ethertap.hh b/src/dev/ethertap.hh
index 3d2838817..5c24be460 100644
--- a/src/dev/ethertap.hh
+++ b/src/dev/ethertap.hh
@@ -38,19 +38,22 @@
#include <queue>
#include <string>
+#include "base/pollevent.hh"
+#include "dev/etherobject.hh"
#include "dev/etherint.hh"
#include "dev/etherpkt.hh"
+#include "params/EtherTap.hh"
#include "sim/eventq.hh"
-#include "base/pollevent.hh"
#include "sim/sim_object.hh"
class TapEvent;
class TapListener;
+class EtherTapInt;
/*
* Interface to connect a simulated ethernet device to the real world
*/
-class EtherTap : public EtherInt
+class EtherTap : public EtherObject
{
protected:
friend class TapEvent;
@@ -73,6 +76,7 @@ class EtherTap : public EtherInt
protected:
std::string device;
std::queue<EthPacketPtr> packetBuffer;
+ EtherTapInt *interface;
void process(int revent);
void enqueue(EthPacketData *packet);
@@ -96,9 +100,18 @@ class EtherTap : public EtherInt
TxEvent txEvent;
public:
- EtherTap(const std::string &name, EtherDump *dump, int port, int bufsz);
+ typedef EtherTapParams Params;
+ EtherTap(const Params *p);
virtual ~EtherTap();
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+ virtual EtherInt *getEthPort(const std::string &if_name, int idx);
+
virtual bool recvPacket(EthPacketPtr packet);
virtual void sendDone();
@@ -106,4 +119,18 @@ class EtherTap : public EtherInt
virtual void unserialize(Checkpoint *cp, const std::string &section);
};
+class EtherTapInt : public EtherInt
+{
+ private:
+ EtherTap *tap;
+ public:
+ EtherTapInt(const std::string &name, EtherTap *t)
+ : EtherInt(name), tap(t)
+ { }
+
+ virtual bool recvPacket(EthPacketPtr pkt) { return tap->recvPacket(pkt); }
+ virtual void sendDone() { tap->sendDone(); }
+};
+
+
#endif // __ETHERTAP_HH__
diff --git a/src/dev/i8254xGBe.cc b/src/dev/i8254xGBe.cc
index d75e37a8a..797f82c13 100644
--- a/src/dev/i8254xGBe.cc
+++ b/src/dev/i8254xGBe.cc
@@ -48,21 +48,22 @@
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "params/IGbE.hh"
-#include "params/IGbEInt.hh"
#include "sim/stats.hh"
#include "sim/system.hh"
using namespace iGbReg;
using namespace Net;
-IGbE::IGbE(Params *p)
- : PciDev(p), etherInt(NULL), drainEvent(NULL), useFlowControl(p->use_flow_control),
+IGbE::IGbE(const Params *p)
+ : EtherDevice(p), etherInt(NULL), drainEvent(NULL), useFlowControl(p->use_flow_control),
rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), rxTick(false),
txTick(false), txFifoTick(false), rdtrEvent(this), radvEvent(this),
tadvEvent(this), tidvEvent(this), tickEvent(this), interEvent(this),
rxDescCache(this, name()+".RxDesc", p->rx_desc_cache_size),
txDescCache(this, name()+".TxDesc", p->tx_desc_cache_size), clock(p->clock)
{
+ etherInt = new IGbEInt(name() + ".int", this);
+
// Initialized internal registers per Intel documentation
// All registers intialized to 0 by per register constructor
regs.ctrl.fd(1);
@@ -108,6 +109,17 @@ IGbE::IGbE(Params *p)
txFifo.clear();
}
+EtherInt*
+IGbE::getEthPort(const std::string &if_name, int idx)
+{
+
+ if (if_name == "interface" && !etherInt) {
+ if (etherInt->getPeer())
+ panic("Port already connected to\n");
+ return etherInt;
+ }
+ return NULL;
+}
Tick
IGbE::writeConfig(PacketPtr pkt)
@@ -1447,20 +1459,6 @@ IGbE::unserialize(Checkpoint *cp, const std::string &section)
rxDescCache.unserialize(cp, csprintf("%s.RxDescCache", section));
}
-IGbEInt *
-IGbEIntParams::create()
-{
- IGbEInt *dev_int = new IGbEInt(name, device);
-
- EtherInt *p = (EtherInt *)peer;
- if (p) {
- dev_int->setPeer(p);
- p->setPeer(dev_int);
- }
-
- return dev_int;
-}
-
IGbE *
IGbEParams::create()
{
diff --git a/src/dev/i8254xGBe.hh b/src/dev/i8254xGBe.hh
index caffb8c4d..95eac4f82 100644
--- a/src/dev/i8254xGBe.hh
+++ b/src/dev/i8254xGBe.hh
@@ -40,6 +40,7 @@
#include "base/inet.hh"
#include "base/statistics.hh"
+#include "dev/etherdevice.hh"
#include "dev/etherint.hh"
#include "dev/etherpkt.hh"
#include "dev/i8254xGBe_defs.hh"
@@ -50,7 +51,7 @@
class IGbEInt;
-class IGbE : public PciDev
+class IGbE : public EtherDevice
{
private:
IGbEInt *etherInt;
@@ -592,9 +593,11 @@ class IGbE : public PciDev
{
return dynamic_cast<const Params *>(_params);
}
- IGbE(Params *params);
+ IGbE(const Params *params);
~IGbE() {}
+ virtual EtherInt *getEthPort(const std::string &if_name, int idx);
+
Tick clock;
inline Tick cycles(int numCycles) const { return numCycles * clock; }
@@ -606,8 +609,6 @@ class IGbE : public PciDev
bool ethRxPkt(EthPacketPtr packet);
void ethTxDone();
- void setEthInt(IGbEInt *i) { assert(!etherInt); etherInt = i; }
-
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
virtual unsigned int drain(Event *de);
@@ -623,7 +624,7 @@ class IGbEInt : public EtherInt
public:
IGbEInt(const std::string &name, IGbE *d)
: EtherInt(name), dev(d)
- { dev->setEthInt(this); }
+ { }
virtual bool recvPacket(EthPacketPtr pkt) { return dev->ethRxPkt(pkt); }
virtual void sendDone() { dev->ethTxDone(); }
diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc
index 28e1100ae..0788b89a9 100644
--- a/src/dev/ns_gige.cc
+++ b/src/dev/ns_gige.cc
@@ -44,7 +44,6 @@
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "params/NSGigE.hh"
-#include "params/NSGigEInt.hh"
#include "sim/debug.hh"
#include "sim/host.hh"
#include "sim/stats.hh"
@@ -90,7 +89,7 @@ using namespace TheISA;
// NSGigE PCI Device
//
NSGigE::NSGigE(Params *p)
- : PciDev(p), ioEnable(false),
+ : EtherDevice(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),
@@ -118,6 +117,8 @@ NSGigE::NSGigE(Params *p)
{
+ interface = new NSGigEInt(name() + ".int0", this);
+
regsReset();
memcpy(&rom.perfectMatch, p->hardware_address.bytes(), ETH_ADDR_LEN);
@@ -492,6 +493,17 @@ NSGigE::writeConfig(PacketPtr pkt)
return configDelay;
}
+EtherInt*
+NSGigE::getEthPort(const std::string &if_name, int idx)
+{
+ if (if_name == "interface") {
+ if (interface->getPeer())
+ panic("interface already connected to\n");
+ return interface;
+ }
+ return NULL;
+}
+
/**
* This reads the device registers, which are detailed in the NS83820
* spec sheet
@@ -2774,20 +2786,6 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
}
}
-NSGigEInt *
-NSGigEIntParams::create()
-{
- NSGigEInt *dev_int = new NSGigEInt(name, device);
-
- EtherInt *p = (EtherInt *)peer;
- if (p) {
- dev_int->setPeer(p);
- p->setPeer(dev_int);
- }
-
- return dev_int;
-}
-
NSGigE *
NSGigEParams::create()
{
diff --git a/src/dev/ns_gige.hh b/src/dev/ns_gige.hh
index de18571d6..5e589687a 100644
--- a/src/dev/ns_gige.hh
+++ b/src/dev/ns_gige.hh
@@ -39,11 +39,11 @@
#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"
#include "dev/ns_gige_reg.h"
-#include "dev/pcidev.hh"
#include "dev/pktfifo.hh"
#include "params/NSGigE.hh"
#include "sim/eventq.hh"
@@ -119,7 +119,7 @@ class Packet;
/**
* NS DP83820 Ethernet device model
*/
-class NSGigE : public PciDev
+class NSGigE : public EtherDevice
{
public:
/** Transmit State Machine states */
@@ -355,6 +355,8 @@ class NSGigE : public PciDev
NSGigE(Params *params);
~NSGigE();
+ virtual EtherInt *getEthPort(const std::string &if_name, int idx);
+
virtual Tick writeConfig(PacketPtr pkt);
virtual Tick read(PacketPtr pkt);
@@ -366,8 +368,6 @@ class NSGigE : public PciDev
bool recvPacket(EthPacketPtr packet);
void transferDone();
- void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
-
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
@@ -438,7 +438,8 @@ class NSGigEInt : public EtherInt
public:
NSGigEInt(const std::string &name, NSGigE *d)
- : EtherInt(name), dev(d) { dev->setInterface(this); }
+ : EtherInt(name), dev(d)
+ { }
virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
virtual void sendDone() { dev->transferDone(); }
diff --git a/src/dev/pcidev.cc b/src/dev/pcidev.cc
index 9efee2835..aa532414c 100644
--- a/src/dev/pcidev.cc
+++ b/src/dev/pcidev.cc
@@ -48,7 +48,6 @@
#include "dev/alpha/tsunamireg.h"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
-#include "params/PciConfigData.hh"
#include "sim/byteswap.hh"
#include "sim/core.hh"
@@ -81,22 +80,58 @@ PciDev::PciConfigPort::getDeviceAddressRanges(AddrRangeList &resp,
}
-PciDev::PciDev(Params *p)
- : DmaDevice(p), plat(p->platform), configData(p->configdata),
- pioDelay(p->pio_latency), configDelay(p->config_latency),
- configPort(NULL)
+PciDev::PciDev(const Params *p)
+ : DmaDevice(p), plat(p->platform), pioDelay(p->pio_latency),
+ configDelay(p->config_latency), configPort(NULL)
{
- // copy the config data from the PciConfigData object
- if (configData) {
- memcpy(config.data, configData->config.data, sizeof(config.data));
- memcpy(BARSize, configData->BARSize, sizeof(BARSize));
- } else
- panic("NULL pointer to configuration data");
+ config.vendor = htole(p->VendorID);
+ config.device = htole(p->DeviceID);
+ config.command = htole(p->Command);
+ config.status = htole(p->Status);
+ config.revision = htole(p->Revision);
+ config.progIF = htole(p->ProgIF);
+ config.subClassCode = htole(p->SubClassCode);
+ config.classCode = htole(p->ClassCode);
+ config.cacheLineSize = htole(p->CacheLineSize);
+ config.latencyTimer = htole(p->LatencyTimer);
+ config.headerType = htole(p->HeaderType);
+ config.bist = htole(p->BIST);
+
+ config.baseAddr[0] = htole(p->BAR0);
+ config.baseAddr[1] = htole(p->BAR1);
+ config.baseAddr[2] = htole(p->BAR2);
+ config.baseAddr[3] = htole(p->BAR3);
+ config.baseAddr[4] = htole(p->BAR4);
+ config.baseAddr[5] = htole(p->BAR5);
+ config.cardbusCIS = htole(p->CardbusCIS);
+ config.subsystemVendorID = htole(p->SubsystemVendorID);
+ config.subsystemID = htole(p->SubsystemID);
+ config.expansionROM = htole(p->ExpansionROM);
+ config.reserved0 = 0;
+ config.reserved1 = 0;
+ config.interruptLine = htole(p->InterruptLine);
+ config.interruptPin = htole(p->InterruptPin);
+ config.minimumGrant = htole(p->MinimumGrant);
+ config.maximumLatency = htole(p->MaximumLatency);
+
+ BARSize[0] = p->BAR0Size;
+ BARSize[1] = p->BAR1Size;
+ BARSize[2] = p->BAR2Size;
+ BARSize[3] = p->BAR3Size;
+ BARSize[4] = p->BAR4Size;
+ BARSize[5] = p->BAR5Size;
+
+ for (int i = 0; i < 6; ++i) {
+ uint32_t barsize = BARSize[i];
+ if (barsize != 0 && !isPowerOf2(barsize)) {
+ fatal("BAR %d size %d is not a power of 2\n", i, BARSize[i]);
+ }
+ }
memset(BARAddrs, 0, sizeof(BARAddrs));
plat->registerPciDevice(0, p->pci_dev, p->pci_func,
- letoh(configData->config.interruptLine));
+ letoh(config.interruptLine));
}
void
@@ -304,53 +339,3 @@ PciDev::unserialize(Checkpoint *cp, const std::string &section)
}
-PciConfigData *
-PciConfigDataParams::create()
-{
- PciConfigData *data = new PciConfigData(name);
-
- data->config.vendor = htole(VendorID);
- data->config.device = htole(DeviceID);
- data->config.command = htole(Command);
- data->config.status = htole(Status);
- data->config.revision = htole(Revision);
- data->config.progIF = htole(ProgIF);
- data->config.subClassCode = htole(SubClassCode);
- data->config.classCode = htole(ClassCode);
- data->config.cacheLineSize = htole(CacheLineSize);
- data->config.latencyTimer = htole(LatencyTimer);
- data->config.headerType = htole(HeaderType);
- data->config.bist = htole(BIST);
-
- data->config.baseAddr[0] = htole(BAR0);
- data->config.baseAddr[1] = htole(BAR1);
- data->config.baseAddr[2] = htole(BAR2);
- data->config.baseAddr[3] = htole(BAR3);
- data->config.baseAddr[4] = htole(BAR4);
- data->config.baseAddr[5] = htole(BAR5);
- data->config.cardbusCIS = htole(CardbusCIS);
- data->config.subsystemVendorID = htole(SubsystemVendorID);
- data->config.subsystemID = htole(SubsystemID);
- data->config.expansionROM = htole(ExpansionROM);
- data->config.interruptLine = htole(InterruptLine);
- data->config.interruptPin = htole(InterruptPin);
- data->config.minimumGrant = htole(MinimumGrant);
- data->config.maximumLatency = htole(MaximumLatency);
-
- data->BARSize[0] = BAR0Size;
- data->BARSize[1] = BAR1Size;
- data->BARSize[2] = BAR2Size;
- data->BARSize[3] = BAR3Size;
- data->BARSize[4] = BAR4Size;
- data->BARSize[5] = BAR5Size;
-
- for (int i = 0; i < 6; ++i) {
- uint32_t barsize = data->BARSize[i];
- if (barsize != 0 && !isPowerOf2(barsize)) {
- fatal("%s: BAR %d size %d is not a power of 2\n",
- name, i, data->BARSize[i]);
- }
- }
-
- return data;
-}
diff --git a/src/dev/pcidev.hh b/src/dev/pcidev.hh
index a08092689..a584a957d 100644
--- a/src/dev/pcidev.hh
+++ b/src/dev/pcidev.hh
@@ -52,30 +52,6 @@
#define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2);
-/**
- * This class encapulates the first 64 bytes of a singles PCI
- * devices config space that in configured by the configuration file.
- */
-class PciConfigData : public SimObject
-{
- public:
- /**
- * Constructor to initialize the devices config space to 0.
- */
- PciConfigData(const std::string &name)
- : SimObject(name)
- {
- std::memset(config.data, 0, sizeof(config.data));
- std::memset(BARSize, 0, sizeof(BARSize));
- }
-
- /** The first 64 bytes */
- PCIConfig config;
-
- /** The size of the BARs */
- uint32_t BARSize[6];
-};
-
/**
* PCI device, base implementation is only config space.
@@ -114,10 +90,7 @@ class PciDev : public DmaDevice
}
protected:
- /** The current config space. Unlike the PciConfigData this is
- * updated during simulation while continues to reflect what was
- * in the config file.
- */
+ /** The current config space. */
PCIConfig config;
/** The size of the BARs */
@@ -174,7 +147,6 @@ class PciDev : public DmaDevice
protected:
Platform *plat;
- PciConfigData *configData;
Tick pioDelay;
Tick configDelay;
PciConfigPort *configPort;
@@ -202,15 +174,15 @@ class PciDev : public DmaDevice
void
intrPost()
- { plat->postPciInt(letoh(configData->config.interruptLine)); }
+ { plat->postPciInt(letoh(config.interruptLine)); }
void
intrClear()
- { plat->clearPciInt(letoh(configData->config.interruptLine)); }
+ { plat->clearPciInt(letoh(config.interruptLine)); }
uint8_t
interruptLine()
- { return letoh(configData->config.interruptLine); }
+ { return letoh(config.interruptLine); }
/** return the address ranges that this device responds to.
* @params range_list range list to populate with ranges
@@ -222,7 +194,7 @@ class PciDev : public DmaDevice
* config file object PCIConfigData and registers the device with
* a PciConfigAll object.
*/
- PciDev(Params *params);
+ PciDev(const Params *params);
virtual void init();
diff --git a/src/dev/sinic.cc b/src/dev/sinic.cc
index ed5ab428c..7457a2b47 100644
--- a/src/dev/sinic.cc
+++ b/src/dev/sinic.cc
@@ -73,14 +73,14 @@ const char *TxStateStrings[] =
//
// Sinic PCI Device
//
-Base::Base(Params *p)
+Base::Base(const Params *p)
: PciDev(p), rxEnable(false), txEnable(false), clock(p->clock),
intrDelay(p->intr_delay), intrTick(0), cpuIntrEnable(false),
cpuPendingIntr(false), intrEvent(0), interface(NULL)
{
}
-Device::Device(Params *p)
+Device::Device(const Params *p)
: Base(p), rxUnique(0), txUnique(0),
virtualRegs(p->virtual_count < 1 ? 1 : p->virtual_count),
rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size),
@@ -89,6 +89,7 @@ Device::Device(Params *p)
dmaReadDelay(p->dma_read_delay), dmaReadFactor(p->dma_read_factor),
dmaWriteDelay(p->dma_write_delay), dmaWriteFactor(p->dma_write_factor)
{
+ interface = new Interface(name() + ".int0", this);
reset();
}
@@ -266,6 +267,19 @@ Device::regStats()
rxPacketRate = rxPackets / simSeconds;
}
+EtherInt*
+Device::getEthPort(const std::string &if_name, int idx)
+{
+ if (if_name == "interface") {
+ if (interface->getPeer())
+ panic("interface already connected to\n");
+
+ return interface;
+ }
+ return NULL;
+}
+
+
void
Device::prepareIO(int cpu, int index)
{
@@ -1595,21 +1609,6 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
/* namespace Sinic */ }
-Sinic::Interface *
-SinicIntParams::create()
-{
- using namespace Sinic;
-
- Interface *dev_int = new Interface(name, device);
-
- if (peer) {
- dev_int->setPeer(peer);
- peer->setPeer(dev_int);
- }
-
- return dev_int;
-}
-
Sinic::Device *
SinicParams::create()
{
diff --git a/src/dev/sinic.hh b/src/dev/sinic.hh
index ab5d0d258..469b28191 100644
--- a/src/dev/sinic.hh
+++ b/src/dev/sinic.hh
@@ -40,7 +40,6 @@
#include "dev/pktfifo.hh"
#include "dev/sinicreg.hh"
#include "params/Sinic.hh"
-#include "params/SinicInt.hh"
#include "sim/eventq.hh"
namespace Sinic {
@@ -84,7 +83,7 @@ class Base : public PciDev
public:
typedef SinicParams Params;
const Params *params() const { return (const Params *)_params; }
- Base(Params *p);
+ Base(const Params *p);
};
class Device : public Base
@@ -231,7 +230,7 @@ class Device : public Base
public:
bool recvPacket(EthPacketPtr packet);
void transferDone();
- void setInterface(Interface *i) { assert(!interface); interface = i; }
+ virtual EtherInt *getEthPort(const std::string &if_name, int idx);
/**
* DMA parameters
@@ -312,7 +311,7 @@ class Device : public Base
virtual void unserialize(Checkpoint *cp, const std::string &section);
public:
- Device(Params *p);
+ Device(const Params *p);
~Device();
};
@@ -326,7 +325,8 @@ class Interface : public EtherInt
public:
Interface(const std::string &name, Device *d)
- : EtherInt(name), dev(d) { dev->setInterface(this); }
+ : EtherInt(name), dev(d)
+ { }
virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
virtual void sendDone() { dev->transferDone(); }
diff --git a/src/python/swig/pyobject.cc b/src/python/swig/pyobject.cc
index 455888c04..5ae2aa177 100644
--- a/src/python/swig/pyobject.cc
+++ b/src/python/swig/pyobject.cc
@@ -34,10 +34,17 @@
#include "base/inifile.hh"
#include "base/output.hh"
+#include "config/full_system.hh"
#include "mem/mem_object.hh"
#include "mem/port.hh"
#include "sim/sim_object.hh"
+#if FULL_SYSTEM
+#include "dev/etherdevice.hh"
+#include "dev/etherobject.hh"
+#include "dev/etherint.hh"
+#endif
+
using namespace std;
/**
@@ -58,6 +65,26 @@ lookupPort(SimObject *so, const std::string &name, int i)
return p;
}
+#if FULL_SYSTEM
+
+EtherInt *
+lookupEthPort(SimObject *so, const std::string &name, int i)
+{
+ EtherObject *eo = dynamic_cast<EtherObject *>(so);
+ EtherDevice *ed = dynamic_cast<EtherDevice *>(so);
+ if (eo == NULL && ed == NULL) {
+ warn("error casting SimObject %s", so->name());
+ return NULL;
+ }
+
+ EtherInt *p = NULL;
+ if (eo)
+ p = eo->getEthPort(name, i);
+ else
+ p = ed->getEthPort(name, i);
+ return p;
+}
+#endif
/**
* Connect the described MemObject ports. Called from Python via SWIG.
@@ -67,6 +94,32 @@ int
connectPorts(SimObject *o1, const std::string &name1, int i1,
SimObject *o2, const std::string &name2, int i2)
{
+ MemObject *mo1, *mo2;
+ mo1 = dynamic_cast<MemObject*>(o1);
+ mo2 = dynamic_cast<MemObject*>(o2);
+
+#if FULL_SYSTEM
+ EtherObject *eo1, *eo2;
+ EtherDevice *ed1, *ed2;
+ eo1 = dynamic_cast<EtherObject*>(o1);
+ ed1 = dynamic_cast<EtherDevice*>(o1);
+
+ eo2 = dynamic_cast<EtherObject*>(o2);
+ ed2 = dynamic_cast<EtherDevice*>(o2);
+
+ if ((eo1 || ed1) && (eo2 || ed2)) {
+ EtherInt *p1 = lookupEthPort(o1, name1, i1);
+ EtherInt *p2 = lookupEthPort(o2, name2, i2);
+
+ if (p1 != NULL && p2 != NULL) {
+
+ p1->setPeer(p2);
+ p2->setPeer(p1);
+
+ return 1;
+ }
+ }
+#endif
Port *p1 = lookupPort(o1, name1, i1);
Port *p2 = lookupPort(o2, name2, i2);
diff --git a/util/style.py b/util/style.py
index 3d7336388..866bef9b8 100644
--- a/util/style.py
+++ b/util/style.py
@@ -298,6 +298,9 @@ def check_whitespace(ui, repo, hooktype, node, parent1, parent2):
wctx = repo.workingctx()
for fname in modified:
+ if not whitespace_file(fname):
+ continue
+
fctx = wctx.filectx(fname)
pctx = fctx.parents()
assert len(pctx) in (1, 2)