Merge with head.
--HG-- extra : convert_revision : 6ce77b5bd4f43ddecd51ea8c66759e4b70d4ad82
This commit is contained in:
commit
a874cb40ab
24 changed files with 508 additions and 304 deletions
|
@ -40,9 +40,7 @@ class CowIdeDisk(IdeDisk):
|
||||||
|
|
||||||
def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
||||||
class BaseTsunami(Tsunami):
|
class BaseTsunami(Tsunami):
|
||||||
ethernet = NSGigE(configdata=NSGigEPciData(),
|
ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0)
|
||||||
pci_bus=0, pci_dev=1, pci_func=0)
|
|
||||||
etherint = NSGigEInt(device=Parent.ethernet)
|
|
||||||
ide = IdeController(disks=[Parent.disk0, Parent.disk2],
|
ide = IdeController(disks=[Parent.disk0, Parent.disk2],
|
||||||
pci_func=0, pci_dev=0, pci_bus=0)
|
pci_func=0, pci_dev=0, pci_bus=0)
|
||||||
|
|
||||||
|
@ -125,8 +123,10 @@ def makeDualRoot(testSystem, driveSystem, dumpfile):
|
||||||
self = Root()
|
self = Root()
|
||||||
self.testsys = testSystem
|
self.testsys = testSystem
|
||||||
self.drivesys = driveSystem
|
self.drivesys = driveSystem
|
||||||
self.etherlink = EtherLink(int1 = Parent.testsys.tsunami.etherint[0],
|
self.etherlink = EtherLink()
|
||||||
int2 = Parent.drivesys.tsunami.etherint[0])
|
self.etherlink.int0 = Parent.testsys.tsunami.ethernet.interface
|
||||||
|
self.etherlink.int1 = Parent.drivesys.tsunami.ethernet.interface
|
||||||
|
|
||||||
if dumpfile:
|
if dumpfile:
|
||||||
self.etherdump = EtherDump(file=dumpfile)
|
self.etherdump = EtherDump(file=dumpfile)
|
||||||
self.etherlink.dump = Parent.etherdump
|
self.etherlink.dump = Parent.etherdump
|
||||||
|
|
|
@ -29,29 +29,28 @@
|
||||||
from m5.SimObject import SimObject
|
from m5.SimObject import SimObject
|
||||||
from m5.params import *
|
from m5.params import *
|
||||||
from m5.proxy import *
|
from m5.proxy import *
|
||||||
from Pci import PciDevice, PciConfigData
|
from Pci import PciDevice
|
||||||
|
|
||||||
class EtherInt(SimObject):
|
class EtherObject(SimObject):
|
||||||
type = 'EtherInt'
|
type = 'EtherObject'
|
||||||
abstract = True
|
abstract = True
|
||||||
peer = Param.EtherInt(NULL, "peer interface")
|
|
||||||
|
|
||||||
class EtherLink(SimObject):
|
class EtherLink(EtherObject):
|
||||||
type = 'EtherLink'
|
type = 'EtherLink'
|
||||||
int1 = Param.EtherInt("interface 1")
|
int0 = Port("interface 0")
|
||||||
int2 = Param.EtherInt("interface 2")
|
int1 = Port("interface 1")
|
||||||
delay = Param.Latency('0us', "packet transmit delay")
|
delay = Param.Latency('0us', "packet transmit delay")
|
||||||
delay_var = Param.Latency('0ns', "packet transmit delay variability")
|
delay_var = Param.Latency('0ns', "packet transmit delay variability")
|
||||||
speed = Param.NetworkBandwidth('1Gbps', "link speed")
|
speed = Param.NetworkBandwidth('1Gbps', "link speed")
|
||||||
dump = Param.EtherDump(NULL, "dump object")
|
dump = Param.EtherDump(NULL, "dump object")
|
||||||
|
|
||||||
class EtherBus(SimObject):
|
class EtherBus(EtherObject):
|
||||||
type = 'EtherBus'
|
type = 'EtherBus'
|
||||||
loopback = Param.Bool(True, "send packet back to the sending interface")
|
loopback = Param.Bool(True, "send packet back to the sending interface")
|
||||||
dump = Param.EtherDump(NULL, "dump object")
|
dump = Param.EtherDump(NULL, "dump object")
|
||||||
speed = Param.NetworkBandwidth('100Mbps', "bus speed in bits per second")
|
speed = Param.NetworkBandwidth('100Mbps', "bus speed in bits per second")
|
||||||
|
|
||||||
class EtherTap(EtherInt):
|
class EtherTap(EtherObject):
|
||||||
type = 'EtherTap'
|
type = 'EtherTap'
|
||||||
bufsz = Param.Int(10000, "tap buffer size")
|
bufsz = Param.Int(10000, "tap buffer size")
|
||||||
dump = Param.EtherDump(NULL, "dump object")
|
dump = Param.EtherDump(NULL, "dump object")
|
||||||
|
@ -62,7 +61,12 @@ class EtherDump(SimObject):
|
||||||
file = Param.String("dump file")
|
file = Param.String("dump file")
|
||||||
maxlen = Param.Int(96, "max portion of packet data to dump")
|
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'
|
type = 'IGbE'
|
||||||
hardware_address = Param.EthernetAddr(NextEthernetAddr,
|
hardware_address = Param.EthernetAddr(NextEthernetAddr,
|
||||||
"Ethernet Hardware Address")
|
"Ethernet Hardware Address")
|
||||||
|
@ -75,8 +79,6 @@ class IGbE(PciDevice):
|
||||||
tx_desc_cache_size = Param.Int(64,
|
tx_desc_cache_size = Param.Int(64,
|
||||||
"Number of enteries in the rx descriptor cache")
|
"Number of enteries in the rx descriptor cache")
|
||||||
clock = Param.Clock('500MHz', "Clock speed of the device")
|
clock = Param.Clock('500MHz', "Clock speed of the device")
|
||||||
|
|
||||||
class IGbEPciData(PciConfigData):
|
|
||||||
VendorID = 0x8086
|
VendorID = 0x8086
|
||||||
DeviceID = 0x1075
|
DeviceID = 0x1075
|
||||||
SubsystemID = 0x1008
|
SubsystemID = 0x1008
|
||||||
|
@ -97,11 +99,7 @@ class IGbEPciData(PciConfigData):
|
||||||
InterruptPin = 0x01
|
InterruptPin = 0x01
|
||||||
BAR0Size = '128kB'
|
BAR0Size = '128kB'
|
||||||
|
|
||||||
class IGbEInt(EtherInt):
|
class EtherDevBase(EtherDevice):
|
||||||
type = 'IGbEInt'
|
|
||||||
device = Param.IGbE("Ethernet device of this interface")
|
|
||||||
|
|
||||||
class EtherDevBase(PciDevice):
|
|
||||||
type = 'EtherDevBase'
|
type = 'EtherDevBase'
|
||||||
abstract = True
|
abstract = True
|
||||||
hardware_address = Param.EthernetAddr(NextEthernetAddr,
|
hardware_address = Param.EthernetAddr(NextEthernetAddr,
|
||||||
|
@ -125,7 +123,13 @@ class EtherDevBase(PciDevice):
|
||||||
tx_thread = Param.Bool(False, "dedicated kernel threads for receive")
|
tx_thread = Param.Bool(False, "dedicated kernel threads for receive")
|
||||||
rss = Param.Bool(False, "Receive Side Scaling")
|
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
|
VendorID = 0x100B
|
||||||
DeviceID = 0x0022
|
DeviceID = 0x0022
|
||||||
Status = 0x0290
|
Status = 0x0290
|
||||||
|
@ -145,38 +149,7 @@ class NSGigEPciData(PciConfigData):
|
||||||
BAR0Size = '256B'
|
BAR0Size = '256B'
|
||||||
BAR1Size = '4kB'
|
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 NSGigEInt(EtherInt):
|
|
||||||
type = 'NSGigEInt'
|
|
||||||
device = Param.NSGigE("Ethernet device of this interface")
|
|
||||||
|
|
||||||
class SinicPciData(PciConfigData):
|
|
||||||
VendorID = 0x1291
|
|
||||||
DeviceID = 0x1293
|
|
||||||
Status = 0x0290
|
|
||||||
SubClassCode = 0x00
|
|
||||||
ClassCode = 0x02
|
|
||||||
ProgIF = 0x00
|
|
||||||
BAR0 = 0x00000000
|
|
||||||
BAR1 = 0x00000000
|
|
||||||
BAR2 = 0x00000000
|
|
||||||
BAR3 = 0x00000000
|
|
||||||
BAR4 = 0x00000000
|
|
||||||
BAR5 = 0x00000000
|
|
||||||
MaximumLatency = 0x34
|
|
||||||
MinimumGrant = 0xb0
|
|
||||||
InterruptLine = 0x1e
|
|
||||||
InterruptPin = 0x01
|
|
||||||
BAR0Size = '64kB'
|
|
||||||
|
|
||||||
class Sinic(EtherDevBase):
|
class Sinic(EtherDevBase):
|
||||||
type = 'Sinic'
|
type = 'Sinic'
|
||||||
|
@ -195,11 +168,22 @@ class Sinic(EtherDevBase):
|
||||||
delay_copy = Param.Bool(False, "Delayed copy transmit")
|
delay_copy = Param.Bool(False, "Delayed copy transmit")
|
||||||
virtual_addr = Param.Bool(False, "Virtual addressing")
|
virtual_addr = Param.Bool(False, "Virtual addressing")
|
||||||
|
|
||||||
configdata = SinicPciData()
|
VendorID = 0x1291
|
||||||
|
DeviceID = 0x1293
|
||||||
|
Status = 0x0290
|
||||||
|
SubClassCode = 0x00
|
||||||
|
ClassCode = 0x02
|
||||||
|
ProgIF = 0x00
|
||||||
|
BAR0 = 0x00000000
|
||||||
|
BAR1 = 0x00000000
|
||||||
|
BAR2 = 0x00000000
|
||||||
|
BAR3 = 0x00000000
|
||||||
|
BAR4 = 0x00000000
|
||||||
|
BAR5 = 0x00000000
|
||||||
|
MaximumLatency = 0x34
|
||||||
|
MinimumGrant = 0xb0
|
||||||
|
InterruptLine = 0x1e
|
||||||
|
InterruptPin = 0x01
|
||||||
|
BAR0Size = '64kB'
|
||||||
|
|
||||||
class SinicInt(EtherInt):
|
|
||||||
type = 'SinicInt'
|
|
||||||
cxx_namespace = 'Sinic'
|
|
||||||
cxx_class = 'Interface'
|
|
||||||
|
|
||||||
device = Param.Sinic("Ethernet device of this interface")
|
|
||||||
|
|
|
@ -28,11 +28,20 @@
|
||||||
|
|
||||||
from m5.SimObject import SimObject
|
from m5.SimObject import SimObject
|
||||||
from m5.params import *
|
from m5.params import *
|
||||||
from Pci import PciDevice, PciConfigData
|
from Pci import PciDevice
|
||||||
|
|
||||||
class IdeID(Enum): vals = ['master', 'slave']
|
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
|
VendorID = 0x8086
|
||||||
DeviceID = 0x7111
|
DeviceID = 0x7111
|
||||||
Command = 0x0
|
Command = 0x0
|
||||||
|
@ -55,14 +64,3 @@ class IdeControllerPciData(PciConfigData):
|
||||||
BAR3Size = '4B'
|
BAR3Size = '4B'
|
||||||
BAR4Size = '16B'
|
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()
|
|
||||||
|
|
|
@ -31,8 +31,23 @@ from m5.params import *
|
||||||
from m5.proxy import *
|
from m5.proxy import *
|
||||||
from Device import BasicPioDevice, DmaDevice, PioDevice
|
from Device import BasicPioDevice, DmaDevice, PioDevice
|
||||||
|
|
||||||
class PciConfigData(SimObject):
|
class PciConfigAll(PioDevice):
|
||||||
type = 'PciConfigData'
|
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")
|
VendorID = Param.UInt16("Vendor ID")
|
||||||
DeviceID = Param.UInt16("Device ID")
|
DeviceID = Param.UInt16("Device ID")
|
||||||
Command = Param.UInt16(0, "Command")
|
Command = Param.UInt16(0, "Command")
|
||||||
|
@ -68,20 +83,4 @@ class PciConfigData(SimObject):
|
||||||
MaximumLatency = Param.UInt8(0x00, "Maximum Latency")
|
MaximumLatency = Param.UInt8(0x00, "Maximum Latency")
|
||||||
MinimumGrant = Param.UInt8(0x00, "Minimum Grant")
|
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")
|
|
||||||
|
|
|
@ -47,10 +47,9 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
EtherBus::EtherBus(const string &name, double speed, bool loop,
|
EtherBus::EtherBus(const Params *p)
|
||||||
EtherDump *packet_dump)
|
: EtherObject(p), ticksPerByte(p->speed), loopback(p->loopback),
|
||||||
: SimObject(name), ticksPerByte(speed), loopback(loop),
|
event(&mainEventQueue, this), sender(0), dump(p->dump)
|
||||||
event(&mainEventQueue, this), sender(0), dump(packet_dump)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,9 +77,11 @@ EtherBus::txDone()
|
||||||
packet = 0;
|
packet = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
EtherInt*
|
||||||
EtherBus::reg(EtherInt *dev)
|
EtherBus::getEthPort(const std::string &if_name, int idx)
|
||||||
{ devlist.push_back(dev); }
|
{
|
||||||
|
panic("Etherbus doesn't work\n");
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EtherBus::send(EtherInt *sndr, EthPacketPtr &pkt)
|
EtherBus::send(EtherInt *sndr, EthPacketPtr &pkt)
|
||||||
|
@ -106,5 +107,5 @@ EtherBus::send(EtherInt *sndr, EthPacketPtr &pkt)
|
||||||
EtherBus *
|
EtherBus *
|
||||||
EtherBusParams::create()
|
EtherBusParams::create()
|
||||||
{
|
{
|
||||||
return new EtherBus(name, speed, loopback, dump);
|
return new EtherBus(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,11 +37,13 @@
|
||||||
|
|
||||||
#include "sim/eventq.hh"
|
#include "sim/eventq.hh"
|
||||||
#include "dev/etherpkt.hh"
|
#include "dev/etherpkt.hh"
|
||||||
|
#include "dev/etherobject.hh"
|
||||||
|
#include "params/EtherBus.hh"
|
||||||
#include "sim/sim_object.hh"
|
#include "sim/sim_object.hh"
|
||||||
|
|
||||||
class EtherDump;
|
class EtherDump;
|
||||||
class EtherInt;
|
class EtherInt;
|
||||||
class EtherBus : public SimObject
|
class EtherBus : public EtherObject
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
typedef std::list<EtherInt *> devlist_t;
|
typedef std::list<EtherInt *> devlist_t;
|
||||||
|
@ -68,14 +70,21 @@ class EtherBus : public SimObject
|
||||||
EtherDump *dump;
|
EtherDump *dump;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EtherBus(const std::string &name, double speed, bool loopback,
|
typedef EtherBusParams Params;
|
||||||
EtherDump *dump);
|
EtherBus(const Params *p);
|
||||||
virtual ~EtherBus() {}
|
virtual ~EtherBus() {}
|
||||||
|
|
||||||
|
const Params *
|
||||||
|
params() const
|
||||||
|
{
|
||||||
|
return dynamic_cast<const Params *>(_params);
|
||||||
|
}
|
||||||
|
|
||||||
void txDone();
|
void txDone();
|
||||||
void reg(EtherInt *dev);
|
void reg(EtherInt *dev);
|
||||||
bool busy() const { return (bool)packet; }
|
bool busy() const { return (bool)packet; }
|
||||||
bool send(EtherInt *sender, EthPacketPtr &packet);
|
bool send(EtherInt *sender, EthPacketPtr &packet);
|
||||||
|
virtual EtherInt *getEthPort(const std::string &if_name, int idx);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ETHERBUS_H__
|
#endif // __ETHERBUS_H__
|
||||||
|
|
69
src/dev/etherdevice.hh
Normal file
69
src/dev/etherdevice.hh
Normal file
|
@ -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__
|
|
@ -39,23 +39,28 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "dev/etherpkt.hh"
|
#include "dev/etherpkt.hh"
|
||||||
#include "sim/sim_object.hh"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class representing the actual interface between two ethernet
|
* Class representing the actual interface between two ethernet
|
||||||
* components. These components are intended to attach to another
|
* components. These components are intended to attach to another
|
||||||
* ethernet interface on one side and whatever device on the other.
|
* ethernet interface on one side and whatever device on the other.
|
||||||
*/
|
*/
|
||||||
class EtherInt : public SimObject
|
class EtherInt
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
mutable std::string portName;
|
||||||
EtherInt *peer;
|
EtherInt *peer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EtherInt(const std::string &name) : SimObject(name), peer(NULL) {}
|
EtherInt(const std::string &name)
|
||||||
|
: portName(name), peer(NULL) {}
|
||||||
virtual ~EtherInt() {}
|
virtual ~EtherInt() {}
|
||||||
|
|
||||||
|
/** Return port name (for DPRINTF). */
|
||||||
|
const std::string &name() const { return portName; }
|
||||||
|
|
||||||
void setPeer(EtherInt *p);
|
void setPeer(EtherInt *p);
|
||||||
|
EtherInt* getPeer() { return peer; }
|
||||||
|
|
||||||
void recvDone() { peer->sendDone(); }
|
void recvDone() { peer->sendDone(); }
|
||||||
virtual void sendDone() = 0;
|
virtual void sendDone() = 0;
|
||||||
|
|
|
@ -51,22 +51,19 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
EtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1,
|
EtherLink::EtherLink(const Params *p)
|
||||||
double rate, Tick delay, Tick delayVar, EtherDump *dump)
|
: EtherObject(p)
|
||||||
: SimObject(name)
|
|
||||||
{
|
{
|
||||||
link[0] = new Link(name + ".link0", this, 0, rate, delay, delayVar, dump);
|
link[0] = new Link(name() + ".link0", this, 0, params()->speed,
|
||||||
link[1] = new Link(name + ".link1", this, 1, rate, delay, delayVar, dump);
|
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[0] = new Interface(name() + ".int0", link[0], link[1]);
|
||||||
interface[1] = new Interface(name + ".int1", link[1], link[0]);
|
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]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EtherLink::~EtherLink()
|
EtherLink::~EtherLink()
|
||||||
{
|
{
|
||||||
delete link[0];
|
delete link[0];
|
||||||
|
@ -76,6 +73,23 @@ EtherLink::~EtherLink()
|
||||||
delete interface[1];
|
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)
|
EtherLink::Interface::Interface(const string &name, Link *tx, Link *rx)
|
||||||
: EtherInt(name), txlink(tx)
|
: EtherInt(name), txlink(tx)
|
||||||
{
|
{
|
||||||
|
@ -275,5 +289,5 @@ REGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent)
|
||||||
EtherLink *
|
EtherLink *
|
||||||
EtherLinkParams::create()
|
EtherLinkParams::create()
|
||||||
{
|
{
|
||||||
return new EtherLink(name, int1, int2, speed, delay, delay_var, dump);
|
return new EtherLink(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,10 @@
|
||||||
#ifndef __DEV_ETHERLINK_HH__
|
#ifndef __DEV_ETHERLINK_HH__
|
||||||
#define __DEV_ETHERLINK_HH__
|
#define __DEV_ETHERLINK_HH__
|
||||||
|
|
||||||
|
#include "dev/etherobject.hh"
|
||||||
#include "dev/etherint.hh"
|
#include "dev/etherint.hh"
|
||||||
#include "dev/etherpkt.hh"
|
#include "dev/etherpkt.hh"
|
||||||
|
#include "params/EtherLink.hh"
|
||||||
#include "sim/eventq.hh"
|
#include "sim/eventq.hh"
|
||||||
#include "sim/host.hh"
|
#include "sim/host.hh"
|
||||||
#include "sim/sim_object.hh"
|
#include "sim/sim_object.hh"
|
||||||
|
@ -46,7 +48,7 @@ class Checkpoint;
|
||||||
/*
|
/*
|
||||||
* Model for a fixed bandwidth full duplex ethernet link
|
* Model for a fixed bandwidth full duplex ethernet link
|
||||||
*/
|
*/
|
||||||
class EtherLink : public SimObject
|
class EtherLink : public EtherObject
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
class Interface;
|
class Interface;
|
||||||
|
@ -118,13 +120,21 @@ class EtherLink : public SimObject
|
||||||
};
|
};
|
||||||
|
|
||||||
Link *link[2];
|
Link *link[2];
|
||||||
EtherInt *interface[2];
|
Interface *interface[2];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EtherLink(const std::string &name, EtherInt *peer0, EtherInt *peer1,
|
typedef EtherLinkParams Params;
|
||||||
double rate, Tick delay, Tick delayVar, EtherDump *dump);
|
EtherLink(const Params *p);
|
||||||
virtual ~EtherLink();
|
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 serialize(std::ostream &os);
|
||||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
|
|
67
src/dev/etherobject.hh
Normal file
67
src/dev/etherobject.hh
Normal file
|
@ -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__
|
|
@ -69,11 +69,17 @@ class EthPacketData : public RefCounted
|
||||||
int slack;
|
int slack;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EthPacketData() : data(NULL), length(0), slack(0) { }
|
EthPacketData() : data(NULL), length(0), slack(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
explicit EthPacketData(size_t size)
|
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)
|
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; }
|
~EthPacketData() { if (data) delete [] data; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
#include "dev/etherint.hh"
|
#include "dev/etherint.hh"
|
||||||
#include "dev/etherpkt.hh"
|
#include "dev/etherpkt.hh"
|
||||||
#include "dev/ethertap.hh"
|
#include "dev/ethertap.hh"
|
||||||
#include "params/EtherTap.hh"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -127,13 +126,14 @@ class TapEvent : public PollEvent
|
||||||
virtual void process(int revent) { tap->process(revent); }
|
virtual void process(int revent) { tap->process(revent); }
|
||||||
};
|
};
|
||||||
|
|
||||||
EtherTap::EtherTap(const string &name, EtherDump *d, int port, int bufsz)
|
EtherTap::EtherTap(const Params *p)
|
||||||
: EtherInt(name), event(NULL), socket(-1), buflen(bufsz), dump(d),
|
: EtherObject(p), event(NULL), socket(-1), buflen(p->bufsz), dump(p->dump),
|
||||||
txEvent(this)
|
interface(NULL), txEvent(this)
|
||||||
{
|
{
|
||||||
buffer = new char[buflen];
|
buffer = new char[buflen];
|
||||||
listener = new TapListener(this, port);
|
listener = new TapListener(this, p->port);
|
||||||
listener->listen();
|
listener->listen();
|
||||||
|
interface = new EtherTapInt(name() + ".interface", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
EtherTap::~EtherTap()
|
EtherTap::~EtherTap()
|
||||||
|
@ -182,7 +182,7 @@ EtherTap::recvPacket(EthPacketPtr packet)
|
||||||
write(socket, &len, sizeof(len));
|
write(socket, &len, sizeof(len));
|
||||||
write(socket, packet->data, packet->length);
|
write(socket, packet->data, packet->length);
|
||||||
|
|
||||||
recvDone();
|
interface->recvDone();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,7 @@ EtherTap::process(int revent)
|
||||||
|
|
||||||
DPRINTF(Ethernet, "EtherTap input len=%d\n", packet->length);
|
DPRINTF(Ethernet, "EtherTap input len=%d\n", packet->length);
|
||||||
DDUMP(EthernetData, packet->data, packet->length);
|
DDUMP(EthernetData, packet->data, packet->length);
|
||||||
if (!sendPacket(packet)) {
|
if (!interface->sendPacket(packet)) {
|
||||||
DPRINTF(Ethernet, "bus busy...buffer for retransmission\n");
|
DPRINTF(Ethernet, "bus busy...buffer for retransmission\n");
|
||||||
packetBuffer.push(packet);
|
packetBuffer.push(packet);
|
||||||
if (!txEvent.scheduled())
|
if (!txEvent.scheduled())
|
||||||
|
@ -253,7 +253,7 @@ EtherTap::retransmit()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EthPacketPtr packet = packetBuffer.front();
|
EthPacketPtr packet = packetBuffer.front();
|
||||||
if (sendPacket(packet)) {
|
if (interface->sendPacket(packet)) {
|
||||||
if (dump)
|
if (dump)
|
||||||
dump->dump(packet);
|
dump->dump(packet);
|
||||||
DPRINTF(Ethernet, "EtherTap retransmit\n");
|
DPRINTF(Ethernet, "EtherTap retransmit\n");
|
||||||
|
@ -265,6 +265,18 @@ EtherTap::retransmit()
|
||||||
txEvent.schedule(curTick + retryTime);
|
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
|
void
|
||||||
|
@ -316,12 +328,5 @@ EtherTap::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
EtherTap *
|
EtherTap *
|
||||||
EtherTapParams::create()
|
EtherTapParams::create()
|
||||||
{
|
{
|
||||||
EtherTap *tap = new EtherTap(name, dump, port, bufsz);
|
return new EtherTap(this);
|
||||||
|
|
||||||
if (peer) {
|
|
||||||
tap->setPeer(peer);
|
|
||||||
peer->setPeer(tap);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tap;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,19 +38,22 @@
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "base/pollevent.hh"
|
||||||
|
#include "dev/etherobject.hh"
|
||||||
#include "dev/etherint.hh"
|
#include "dev/etherint.hh"
|
||||||
#include "dev/etherpkt.hh"
|
#include "dev/etherpkt.hh"
|
||||||
|
#include "params/EtherTap.hh"
|
||||||
#include "sim/eventq.hh"
|
#include "sim/eventq.hh"
|
||||||
#include "base/pollevent.hh"
|
|
||||||
#include "sim/sim_object.hh"
|
#include "sim/sim_object.hh"
|
||||||
|
|
||||||
class TapEvent;
|
class TapEvent;
|
||||||
class TapListener;
|
class TapListener;
|
||||||
|
class EtherTapInt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interface to connect a simulated ethernet device to the real world
|
* Interface to connect a simulated ethernet device to the real world
|
||||||
*/
|
*/
|
||||||
class EtherTap : public EtherInt
|
class EtherTap : public EtherObject
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
friend class TapEvent;
|
friend class TapEvent;
|
||||||
|
@ -73,6 +76,7 @@ class EtherTap : public EtherInt
|
||||||
protected:
|
protected:
|
||||||
std::string device;
|
std::string device;
|
||||||
std::queue<EthPacketPtr> packetBuffer;
|
std::queue<EthPacketPtr> packetBuffer;
|
||||||
|
EtherTapInt *interface;
|
||||||
|
|
||||||
void process(int revent);
|
void process(int revent);
|
||||||
void enqueue(EthPacketData *packet);
|
void enqueue(EthPacketData *packet);
|
||||||
|
@ -96,9 +100,18 @@ class EtherTap : public EtherInt
|
||||||
TxEvent txEvent;
|
TxEvent txEvent;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EtherTap(const std::string &name, EtherDump *dump, int port, int bufsz);
|
typedef EtherTapParams Params;
|
||||||
|
EtherTap(const Params *p);
|
||||||
virtual ~EtherTap();
|
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 bool recvPacket(EthPacketPtr packet);
|
||||||
virtual void sendDone();
|
virtual void sendDone();
|
||||||
|
|
||||||
|
@ -106,4 +119,18 @@ class EtherTap : public EtherInt
|
||||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
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__
|
#endif // __ETHERTAP_HH__
|
||||||
|
|
|
@ -48,21 +48,22 @@
|
||||||
#include "mem/packet.hh"
|
#include "mem/packet.hh"
|
||||||
#include "mem/packet_access.hh"
|
#include "mem/packet_access.hh"
|
||||||
#include "params/IGbE.hh"
|
#include "params/IGbE.hh"
|
||||||
#include "params/IGbEInt.hh"
|
|
||||||
#include "sim/stats.hh"
|
#include "sim/stats.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
using namespace iGbReg;
|
using namespace iGbReg;
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
|
|
||||||
IGbE::IGbE(Params *p)
|
IGbE::IGbE(const Params *p)
|
||||||
: PciDev(p), etherInt(NULL), drainEvent(NULL), useFlowControl(p->use_flow_control),
|
: EtherDevice(p), etherInt(NULL), drainEvent(NULL), useFlowControl(p->use_flow_control),
|
||||||
rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), rxTick(false),
|
rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), rxTick(false),
|
||||||
txTick(false), txFifoTick(false), rdtrEvent(this), radvEvent(this),
|
txTick(false), txFifoTick(false), rdtrEvent(this), radvEvent(this),
|
||||||
tadvEvent(this), tidvEvent(this), tickEvent(this), interEvent(this),
|
tadvEvent(this), tidvEvent(this), tickEvent(this), interEvent(this),
|
||||||
rxDescCache(this, name()+".RxDesc", p->rx_desc_cache_size),
|
rxDescCache(this, name()+".RxDesc", p->rx_desc_cache_size),
|
||||||
txDescCache(this, name()+".TxDesc", p->tx_desc_cache_size), clock(p->clock)
|
txDescCache(this, name()+".TxDesc", p->tx_desc_cache_size), clock(p->clock)
|
||||||
{
|
{
|
||||||
|
etherInt = new IGbEInt(name() + ".int", this);
|
||||||
|
|
||||||
// Initialized internal registers per Intel documentation
|
// Initialized internal registers per Intel documentation
|
||||||
// All registers intialized to 0 by per register constructor
|
// All registers intialized to 0 by per register constructor
|
||||||
regs.ctrl.fd(1);
|
regs.ctrl.fd(1);
|
||||||
|
@ -108,6 +109,17 @@ IGbE::IGbE(Params *p)
|
||||||
txFifo.clear();
|
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
|
Tick
|
||||||
IGbE::writeConfig(PacketPtr pkt)
|
IGbE::writeConfig(PacketPtr pkt)
|
||||||
|
@ -1447,20 +1459,6 @@ IGbE::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
rxDescCache.unserialize(cp, csprintf("%s.RxDescCache", 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 *
|
IGbE *
|
||||||
IGbEParams::create()
|
IGbEParams::create()
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
|
|
||||||
#include "base/inet.hh"
|
#include "base/inet.hh"
|
||||||
#include "base/statistics.hh"
|
#include "base/statistics.hh"
|
||||||
|
#include "dev/etherdevice.hh"
|
||||||
#include "dev/etherint.hh"
|
#include "dev/etherint.hh"
|
||||||
#include "dev/etherpkt.hh"
|
#include "dev/etherpkt.hh"
|
||||||
#include "dev/i8254xGBe_defs.hh"
|
#include "dev/i8254xGBe_defs.hh"
|
||||||
|
@ -50,7 +51,7 @@
|
||||||
|
|
||||||
class IGbEInt;
|
class IGbEInt;
|
||||||
|
|
||||||
class IGbE : public PciDev
|
class IGbE : public EtherDevice
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
IGbEInt *etherInt;
|
IGbEInt *etherInt;
|
||||||
|
@ -592,9 +593,11 @@ class IGbE : public PciDev
|
||||||
{
|
{
|
||||||
return dynamic_cast<const Params *>(_params);
|
return dynamic_cast<const Params *>(_params);
|
||||||
}
|
}
|
||||||
IGbE(Params *params);
|
IGbE(const Params *params);
|
||||||
~IGbE() {}
|
~IGbE() {}
|
||||||
|
|
||||||
|
virtual EtherInt *getEthPort(const std::string &if_name, int idx);
|
||||||
|
|
||||||
Tick clock;
|
Tick clock;
|
||||||
inline Tick cycles(int numCycles) const { return numCycles * clock; }
|
inline Tick cycles(int numCycles) const { return numCycles * clock; }
|
||||||
|
|
||||||
|
@ -606,8 +609,6 @@ class IGbE : public PciDev
|
||||||
bool ethRxPkt(EthPacketPtr packet);
|
bool ethRxPkt(EthPacketPtr packet);
|
||||||
void ethTxDone();
|
void ethTxDone();
|
||||||
|
|
||||||
void setEthInt(IGbEInt *i) { assert(!etherInt); etherInt = i; }
|
|
||||||
|
|
||||||
virtual void serialize(std::ostream &os);
|
virtual void serialize(std::ostream &os);
|
||||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
virtual unsigned int drain(Event *de);
|
virtual unsigned int drain(Event *de);
|
||||||
|
@ -623,7 +624,7 @@ class IGbEInt : public EtherInt
|
||||||
public:
|
public:
|
||||||
IGbEInt(const std::string &name, IGbE *d)
|
IGbEInt(const std::string &name, IGbE *d)
|
||||||
: EtherInt(name), dev(d)
|
: EtherInt(name), dev(d)
|
||||||
{ dev->setEthInt(this); }
|
{ }
|
||||||
|
|
||||||
virtual bool recvPacket(EthPacketPtr pkt) { return dev->ethRxPkt(pkt); }
|
virtual bool recvPacket(EthPacketPtr pkt) { return dev->ethRxPkt(pkt); }
|
||||||
virtual void sendDone() { dev->ethTxDone(); }
|
virtual void sendDone() { dev->ethTxDone(); }
|
||||||
|
|
|
@ -44,7 +44,6 @@
|
||||||
#include "mem/packet.hh"
|
#include "mem/packet.hh"
|
||||||
#include "mem/packet_access.hh"
|
#include "mem/packet_access.hh"
|
||||||
#include "params/NSGigE.hh"
|
#include "params/NSGigE.hh"
|
||||||
#include "params/NSGigEInt.hh"
|
|
||||||
#include "sim/debug.hh"
|
#include "sim/debug.hh"
|
||||||
#include "sim/host.hh"
|
#include "sim/host.hh"
|
||||||
#include "sim/stats.hh"
|
#include "sim/stats.hh"
|
||||||
|
@ -90,7 +89,7 @@ using namespace TheISA;
|
||||||
// NSGigE PCI Device
|
// NSGigE PCI Device
|
||||||
//
|
//
|
||||||
NSGigE::NSGigE(Params *p)
|
NSGigE::NSGigE(Params *p)
|
||||||
: PciDev(p), ioEnable(false),
|
: EtherDevice(p), ioEnable(false),
|
||||||
txFifo(p->tx_fifo_size), rxFifo(p->rx_fifo_size),
|
txFifo(p->tx_fifo_size), rxFifo(p->rx_fifo_size),
|
||||||
txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL),
|
txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL),
|
||||||
txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
|
txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
|
||||||
|
@ -118,6 +117,8 @@ NSGigE::NSGigE(Params *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
interface = new NSGigEInt(name() + ".int0", this);
|
||||||
|
|
||||||
regsReset();
|
regsReset();
|
||||||
memcpy(&rom.perfectMatch, p->hardware_address.bytes(), ETH_ADDR_LEN);
|
memcpy(&rom.perfectMatch, p->hardware_address.bytes(), ETH_ADDR_LEN);
|
||||||
|
|
||||||
|
@ -492,6 +493,17 @@ NSGigE::writeConfig(PacketPtr pkt)
|
||||||
return configDelay;
|
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
|
* This reads the device registers, which are detailed in the NS83820
|
||||||
* spec sheet
|
* 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 *
|
NSGigE *
|
||||||
NSGigEParams::create()
|
NSGigEParams::create()
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,11 +39,11 @@
|
||||||
|
|
||||||
#include "base/inet.hh"
|
#include "base/inet.hh"
|
||||||
#include "base/statistics.hh"
|
#include "base/statistics.hh"
|
||||||
|
#include "dev/etherdevice.hh"
|
||||||
#include "dev/etherint.hh"
|
#include "dev/etherint.hh"
|
||||||
#include "dev/etherpkt.hh"
|
#include "dev/etherpkt.hh"
|
||||||
#include "dev/io_device.hh"
|
#include "dev/io_device.hh"
|
||||||
#include "dev/ns_gige_reg.h"
|
#include "dev/ns_gige_reg.h"
|
||||||
#include "dev/pcidev.hh"
|
|
||||||
#include "dev/pktfifo.hh"
|
#include "dev/pktfifo.hh"
|
||||||
#include "params/NSGigE.hh"
|
#include "params/NSGigE.hh"
|
||||||
#include "sim/eventq.hh"
|
#include "sim/eventq.hh"
|
||||||
|
@ -119,7 +119,7 @@ class Packet;
|
||||||
/**
|
/**
|
||||||
* NS DP83820 Ethernet device model
|
* NS DP83820 Ethernet device model
|
||||||
*/
|
*/
|
||||||
class NSGigE : public PciDev
|
class NSGigE : public EtherDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Transmit State Machine states */
|
/** Transmit State Machine states */
|
||||||
|
@ -355,6 +355,8 @@ class NSGigE : public PciDev
|
||||||
NSGigE(Params *params);
|
NSGigE(Params *params);
|
||||||
~NSGigE();
|
~NSGigE();
|
||||||
|
|
||||||
|
virtual EtherInt *getEthPort(const std::string &if_name, int idx);
|
||||||
|
|
||||||
virtual Tick writeConfig(PacketPtr pkt);
|
virtual Tick writeConfig(PacketPtr pkt);
|
||||||
|
|
||||||
virtual Tick read(PacketPtr pkt);
|
virtual Tick read(PacketPtr pkt);
|
||||||
|
@ -366,8 +368,6 @@ class NSGigE : public PciDev
|
||||||
bool recvPacket(EthPacketPtr packet);
|
bool recvPacket(EthPacketPtr packet);
|
||||||
void transferDone();
|
void transferDone();
|
||||||
|
|
||||||
void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
|
|
||||||
|
|
||||||
virtual void serialize(std::ostream &os);
|
virtual void serialize(std::ostream &os);
|
||||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
|
@ -438,7 +438,8 @@ class NSGigEInt : public EtherInt
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NSGigEInt(const std::string &name, NSGigE *d)
|
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 bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
|
||||||
virtual void sendDone() { dev->transferDone(); }
|
virtual void sendDone() { dev->transferDone(); }
|
||||||
|
|
|
@ -48,7 +48,6 @@
|
||||||
#include "dev/alpha/tsunamireg.h"
|
#include "dev/alpha/tsunamireg.h"
|
||||||
#include "mem/packet.hh"
|
#include "mem/packet.hh"
|
||||||
#include "mem/packet_access.hh"
|
#include "mem/packet_access.hh"
|
||||||
#include "params/PciConfigData.hh"
|
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
#include "sim/core.hh"
|
#include "sim/core.hh"
|
||||||
|
|
||||||
|
@ -81,22 +80,58 @@ PciDev::PciConfigPort::getDeviceAddressRanges(AddrRangeList &resp,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PciDev::PciDev(Params *p)
|
PciDev::PciDev(const Params *p)
|
||||||
: DmaDevice(p), plat(p->platform), configData(p->configdata),
|
: DmaDevice(p), plat(p->platform), pioDelay(p->pio_latency),
|
||||||
pioDelay(p->pio_latency), configDelay(p->config_latency),
|
configDelay(p->config_latency), configPort(NULL)
|
||||||
configPort(NULL)
|
|
||||||
{
|
{
|
||||||
// copy the config data from the PciConfigData object
|
config.vendor = htole(p->VendorID);
|
||||||
if (configData) {
|
config.device = htole(p->DeviceID);
|
||||||
memcpy(config.data, configData->config.data, sizeof(config.data));
|
config.command = htole(p->Command);
|
||||||
memcpy(BARSize, configData->BARSize, sizeof(BARSize));
|
config.status = htole(p->Status);
|
||||||
} else
|
config.revision = htole(p->Revision);
|
||||||
panic("NULL pointer to configuration data");
|
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));
|
memset(BARAddrs, 0, sizeof(BARAddrs));
|
||||||
|
|
||||||
plat->registerPciDevice(0, p->pci_dev, p->pci_func,
|
plat->registerPciDevice(0, p->pci_dev, p->pci_func,
|
||||||
letoh(configData->config.interruptLine));
|
letoh(config.interruptLine));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -52,30 +52,6 @@
|
||||||
#define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2);
|
#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.
|
* PCI device, base implementation is only config space.
|
||||||
|
@ -114,10 +90,7 @@ class PciDev : public DmaDevice
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** The current config space. Unlike the PciConfigData this is
|
/** The current config space. */
|
||||||
* updated during simulation while continues to reflect what was
|
|
||||||
* in the config file.
|
|
||||||
*/
|
|
||||||
PCIConfig config;
|
PCIConfig config;
|
||||||
|
|
||||||
/** The size of the BARs */
|
/** The size of the BARs */
|
||||||
|
@ -174,7 +147,6 @@ class PciDev : public DmaDevice
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Platform *plat;
|
Platform *plat;
|
||||||
PciConfigData *configData;
|
|
||||||
Tick pioDelay;
|
Tick pioDelay;
|
||||||
Tick configDelay;
|
Tick configDelay;
|
||||||
PciConfigPort *configPort;
|
PciConfigPort *configPort;
|
||||||
|
@ -202,15 +174,15 @@ class PciDev : public DmaDevice
|
||||||
|
|
||||||
void
|
void
|
||||||
intrPost()
|
intrPost()
|
||||||
{ plat->postPciInt(letoh(configData->config.interruptLine)); }
|
{ plat->postPciInt(letoh(config.interruptLine)); }
|
||||||
|
|
||||||
void
|
void
|
||||||
intrClear()
|
intrClear()
|
||||||
{ plat->clearPciInt(letoh(configData->config.interruptLine)); }
|
{ plat->clearPciInt(letoh(config.interruptLine)); }
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
interruptLine()
|
interruptLine()
|
||||||
{ return letoh(configData->config.interruptLine); }
|
{ return letoh(config.interruptLine); }
|
||||||
|
|
||||||
/** return the address ranges that this device responds to.
|
/** return the address ranges that this device responds to.
|
||||||
* @params range_list range list to populate with ranges
|
* @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
|
* config file object PCIConfigData and registers the device with
|
||||||
* a PciConfigAll object.
|
* a PciConfigAll object.
|
||||||
*/
|
*/
|
||||||
PciDev(Params *params);
|
PciDev(const Params *params);
|
||||||
|
|
||||||
virtual void init();
|
virtual void init();
|
||||||
|
|
||||||
|
|
|
@ -73,14 +73,14 @@ const char *TxStateStrings[] =
|
||||||
//
|
//
|
||||||
// Sinic PCI Device
|
// Sinic PCI Device
|
||||||
//
|
//
|
||||||
Base::Base(Params *p)
|
Base::Base(const Params *p)
|
||||||
: PciDev(p), rxEnable(false), txEnable(false), clock(p->clock),
|
: PciDev(p), rxEnable(false), txEnable(false), clock(p->clock),
|
||||||
intrDelay(p->intr_delay), intrTick(0), cpuIntrEnable(false),
|
intrDelay(p->intr_delay), intrTick(0), cpuIntrEnable(false),
|
||||||
cpuPendingIntr(false), intrEvent(0), interface(NULL)
|
cpuPendingIntr(false), intrEvent(0), interface(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::Device(Params *p)
|
Device::Device(const Params *p)
|
||||||
: Base(p), rxUnique(0), txUnique(0),
|
: Base(p), rxUnique(0), txUnique(0),
|
||||||
virtualRegs(p->virtual_count < 1 ? 1 : p->virtual_count),
|
virtualRegs(p->virtual_count < 1 ? 1 : p->virtual_count),
|
||||||
rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size),
|
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),
|
dmaReadDelay(p->dma_read_delay), dmaReadFactor(p->dma_read_factor),
|
||||||
dmaWriteDelay(p->dma_write_delay), dmaWriteFactor(p->dma_write_factor)
|
dmaWriteDelay(p->dma_write_delay), dmaWriteFactor(p->dma_write_factor)
|
||||||
{
|
{
|
||||||
|
interface = new Interface(name() + ".int0", this);
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -266,6 +267,19 @@ Device::regStats()
|
||||||
rxPacketRate = rxPackets / simSeconds;
|
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
|
void
|
||||||
Device::prepareIO(int cpu, int index)
|
Device::prepareIO(int cpu, int index)
|
||||||
{
|
{
|
||||||
|
@ -1595,21 +1609,6 @@ Device::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
|
|
||||||
/* namespace Sinic */ }
|
/* 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 *
|
Sinic::Device *
|
||||||
SinicParams::create()
|
SinicParams::create()
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#include "dev/pktfifo.hh"
|
#include "dev/pktfifo.hh"
|
||||||
#include "dev/sinicreg.hh"
|
#include "dev/sinicreg.hh"
|
||||||
#include "params/Sinic.hh"
|
#include "params/Sinic.hh"
|
||||||
#include "params/SinicInt.hh"
|
|
||||||
#include "sim/eventq.hh"
|
#include "sim/eventq.hh"
|
||||||
|
|
||||||
namespace Sinic {
|
namespace Sinic {
|
||||||
|
@ -84,7 +83,7 @@ class Base : public PciDev
|
||||||
public:
|
public:
|
||||||
typedef SinicParams Params;
|
typedef SinicParams Params;
|
||||||
const Params *params() const { return (const Params *)_params; }
|
const Params *params() const { return (const Params *)_params; }
|
||||||
Base(Params *p);
|
Base(const Params *p);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Device : public Base
|
class Device : public Base
|
||||||
|
@ -231,7 +230,7 @@ class Device : public Base
|
||||||
public:
|
public:
|
||||||
bool recvPacket(EthPacketPtr packet);
|
bool recvPacket(EthPacketPtr packet);
|
||||||
void transferDone();
|
void transferDone();
|
||||||
void setInterface(Interface *i) { assert(!interface); interface = i; }
|
virtual EtherInt *getEthPort(const std::string &if_name, int idx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DMA parameters
|
* DMA parameters
|
||||||
|
@ -312,7 +311,7 @@ class Device : public Base
|
||||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Device(Params *p);
|
Device(const Params *p);
|
||||||
~Device();
|
~Device();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -326,7 +325,8 @@ class Interface : public EtherInt
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Interface(const std::string &name, Device *d)
|
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 bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
|
||||||
virtual void sendDone() { dev->transferDone(); }
|
virtual void sendDone() { dev->transferDone(); }
|
||||||
|
|
|
@ -34,10 +34,17 @@
|
||||||
|
|
||||||
#include "base/inifile.hh"
|
#include "base/inifile.hh"
|
||||||
#include "base/output.hh"
|
#include "base/output.hh"
|
||||||
|
#include "config/full_system.hh"
|
||||||
#include "mem/mem_object.hh"
|
#include "mem/mem_object.hh"
|
||||||
#include "mem/port.hh"
|
#include "mem/port.hh"
|
||||||
#include "sim/sim_object.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;
|
using namespace std;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,6 +65,26 @@ lookupPort(SimObject *so, const std::string &name, int i)
|
||||||
return p;
|
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.
|
* Connect the described MemObject ports. Called from Python via SWIG.
|
||||||
|
@ -67,6 +94,32 @@ int
|
||||||
connectPorts(SimObject *o1, const std::string &name1, int i1,
|
connectPorts(SimObject *o1, const std::string &name1, int i1,
|
||||||
SimObject *o2, const std::string &name2, int i2)
|
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 *p1 = lookupPort(o1, name1, i1);
|
||||||
Port *p2 = lookupPort(o2, name2, i2);
|
Port *p2 = lookupPort(o2, name2, i2);
|
||||||
|
|
||||||
|
|
|
@ -298,6 +298,9 @@ def check_whitespace(ui, repo, hooktype, node, parent1, parent2):
|
||||||
|
|
||||||
wctx = repo.workingctx()
|
wctx = repo.workingctx()
|
||||||
for fname in modified:
|
for fname in modified:
|
||||||
|
if not whitespace_file(fname):
|
||||||
|
continue
|
||||||
|
|
||||||
fctx = wctx.filectx(fname)
|
fctx = wctx.filectx(fname)
|
||||||
pctx = fctx.parents()
|
pctx = fctx.parents()
|
||||||
assert len(pctx) in (1, 2)
|
assert len(pctx) in (1, 2)
|
||||||
|
|
Loading…
Reference in a new issue