diff options
-rw-r--r-- | configs/common/FSConfig.py | 10 | ||||
-rw-r--r-- | src/dev/Ethernet.py | 90 | ||||
-rw-r--r-- | src/dev/Ide.py | 24 | ||||
-rw-r--r-- | src/dev/Pci.py | 35 | ||||
-rw-r--r-- | src/dev/etherbus.cc | 17 | ||||
-rw-r--r-- | src/dev/etherbus.hh | 15 | ||||
-rw-r--r-- | src/dev/etherdevice.hh | 69 | ||||
-rw-r--r-- | src/dev/etherint.hh | 11 | ||||
-rw-r--r-- | src/dev/etherlink.cc | 40 | ||||
-rw-r--r-- | src/dev/etherlink.hh | 18 | ||||
-rw-r--r-- | src/dev/etherobject.hh | 67 | ||||
-rw-r--r-- | src/dev/etherpkt.hh | 12 | ||||
-rw-r--r-- | src/dev/ethertap.cc | 37 | ||||
-rw-r--r-- | src/dev/ethertap.hh | 33 | ||||
-rw-r--r-- | src/dev/i8254xGBe.cc | 32 | ||||
-rw-r--r-- | src/dev/i8254xGBe.hh | 11 | ||||
-rw-r--r-- | src/dev/ns_gige.cc | 30 | ||||
-rw-r--r-- | src/dev/ns_gige.hh | 11 | ||||
-rw-r--r-- | src/dev/pcidev.cc | 109 | ||||
-rw-r--r-- | src/dev/pcidev.hh | 38 | ||||
-rw-r--r-- | src/dev/sinic.cc | 33 | ||||
-rw-r--r-- | src/dev/sinic.hh | 10 | ||||
-rw-r--r-- | src/python/swig/pyobject.cc | 53 | ||||
-rw-r--r-- | util/style.py | 3 |
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 §ion); 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 §ion) 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 §ion); }; +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 §ion) 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 §ion); 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 §ion) } } -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 §ion); @@ -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 §ion) } -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 §ion) /* 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 §ion); 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) |