Mostly done with all device models for new memory system. Still need to get timing packets working and get sinic working
after merge from head. Checkpointing may need some work now. Endian-happiness still not complete. SConscript: add all devices back into make file base/inet.hh: dev/etherbus.cc: dev/etherbus.hh: dev/etherdump.cc: dev/etherdump.hh: dev/etherint.hh: dev/etherlink.cc: dev/etherlink.hh: dev/etherpkt.cc: dev/etherpkt.hh: dev/ethertap.cc: dev/ethertap.hh: dev/pktfifo.cc: dev/pktfifo.hh: rename PacketPtr EthPacketPtr so it doesn't conflict with the PacketPtr type in the memory system configs/test/fs.py: add nics to fs.py cpu/cpu_exec_context.cc: remove this check, as it's not valid. We may want to add something else back in to make sure that no one can delete the static virtual ports in the exec context cpu/simple/cpu.cc: cpu/simple/cpu.hh: dev/alpha_console.cc: dev/ide_ctrl.cc: use new methods for accessing packet data dev/ide_disk.cc: add some more dprintfs dev/io_device.cc: delete packets when we are done with them. Update for new packet methods to access data dev/isa_fake.cc: dev/pciconfigall.cc: dev/tsunami_cchip.cc: dev/tsunami_io.cc: dev/tsunami_pchip.cc: dev/uart8250.cc: dev/uart8250.hh: mem/physical.cc: mem/port.cc: dUpdate for new packet methods to access data dev/ns_gige.cc: Update for new memory system dev/ns_gige.hh: python/m5/objects/Ethernet.py: update for new memory system dev/sinic.cc: dev/sinic.hh: Update for new memory system. Untested as need to merge in head because of kernel driver differences between versions mem/packet.hh: Add methods to access data instead of accessing it directly. --HG-- extra : convert_revision : 223f43876afd404e68337270cd9a5e44d0bf553e
This commit is contained in:
parent
6dc3b2fa39
commit
8f8d09538f
39 changed files with 891 additions and 1217 deletions
22
SConscript
22
SConscript
|
@ -186,15 +186,25 @@ full_system_sources = Split('''
|
||||||
dev/alpha_console.cc
|
dev/alpha_console.cc
|
||||||
dev/baddev.cc
|
dev/baddev.cc
|
||||||
dev/disk_image.cc
|
dev/disk_image.cc
|
||||||
dev/ide_ctrl.cc
|
dev/etherbus.cc
|
||||||
|
dev/etherdump.cc
|
||||||
|
dev/etherint.cc
|
||||||
|
dev/etherlink.cc
|
||||||
|
dev/etherpkt.cc
|
||||||
|
dev/ethertap.cc
|
||||||
|
dev/ide_ctrl.cc
|
||||||
dev/ide_disk.cc
|
dev/ide_disk.cc
|
||||||
dev/io_device.cc
|
dev/io_device.cc
|
||||||
dev/isa_fake.cc
|
dev/isa_fake.cc
|
||||||
|
dev/ns_gige.cc
|
||||||
dev/pciconfigall.cc
|
dev/pciconfigall.cc
|
||||||
dev/pcidev.cc
|
dev/pcidev.cc
|
||||||
|
dev/pcifake.cc
|
||||||
|
dev/pktfifo.cc
|
||||||
dev/platform.cc
|
dev/platform.cc
|
||||||
dev/simconsole.cc
|
dev/simconsole.cc
|
||||||
dev/simple_disk.cc
|
dev/simple_disk.cc
|
||||||
|
dev/sinic.cc
|
||||||
dev/tsunami.cc
|
dev/tsunami.cc
|
||||||
dev/tsunami_cchip.cc
|
dev/tsunami_cchip.cc
|
||||||
dev/tsunami_io.cc
|
dev/tsunami_io.cc
|
||||||
|
@ -216,16 +226,6 @@ full_system_sources = Split('''
|
||||||
sim/pseudo_inst.cc
|
sim/pseudo_inst.cc
|
||||||
''')
|
''')
|
||||||
|
|
||||||
# dev/etherbus.cc
|
|
||||||
# dev/etherdump.cc
|
|
||||||
# dev/etherint.cc
|
|
||||||
# dev/etherlink.cc
|
|
||||||
# dev/etherpkt.cc
|
|
||||||
# dev/ethertap.cc
|
|
||||||
# dev/ns_gige.cc
|
|
||||||
# dev/pcifake.cc
|
|
||||||
# dev/pktfifo.cc
|
|
||||||
# dev/sinic.cc
|
|
||||||
|
|
||||||
if env['TARGET_ISA'] == 'alpha':
|
if env['TARGET_ISA'] == 'alpha':
|
||||||
full_system_sources += Split('''
|
full_system_sources += Split('''
|
||||||
|
|
38
base/inet.hh
38
base/inet.hh
|
@ -117,11 +117,11 @@ class EthPtr
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
friend class IpPtr;
|
friend class IpPtr;
|
||||||
PacketPtr p;
|
EthPacketPtr p;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EthPtr() {}
|
EthPtr() {}
|
||||||
EthPtr(const PacketPtr &ptr) : p(ptr) { }
|
EthPtr(const EthPacketPtr &ptr) : p(ptr) { }
|
||||||
|
|
||||||
EthHdr *operator->() { return (EthHdr *)p->data; }
|
EthHdr *operator->() { return (EthHdr *)p->data; }
|
||||||
EthHdr &operator*() { return *(EthHdr *)p->data; }
|
EthHdr &operator*() { return *(EthHdr *)p->data; }
|
||||||
|
@ -131,10 +131,10 @@ class EthPtr
|
||||||
const EthHdr &operator*() const { return *(const EthHdr *)p->data; }
|
const EthHdr &operator*() const { return *(const EthHdr *)p->data; }
|
||||||
operator const EthHdr *() const { return (const EthHdr *)p->data; }
|
operator const EthHdr *() const { return (const EthHdr *)p->data; }
|
||||||
|
|
||||||
const EthPtr &operator=(const PacketPtr &ptr) { p = ptr; return *this; }
|
const EthPtr &operator=(const EthPacketPtr &ptr) { p = ptr; return *this; }
|
||||||
|
|
||||||
const PacketPtr packet() const { return p; }
|
const EthPacketPtr packet() const { return p; }
|
||||||
PacketPtr packet() { return p; }
|
EthPacketPtr packet() { return p; }
|
||||||
bool operator!() const { return !p; }
|
bool operator!() const { return !p; }
|
||||||
operator bool() const { return p; }
|
operator bool() const { return p; }
|
||||||
};
|
};
|
||||||
|
@ -174,13 +174,13 @@ class IpPtr
|
||||||
protected:
|
protected:
|
||||||
friend class TcpPtr;
|
friend class TcpPtr;
|
||||||
friend class UdpPtr;
|
friend class UdpPtr;
|
||||||
PacketPtr p;
|
EthPacketPtr p;
|
||||||
|
|
||||||
const IpHdr *h() const
|
const IpHdr *h() const
|
||||||
{ return (const IpHdr *)(p->data + sizeof(eth_hdr)); }
|
{ return (const IpHdr *)(p->data + sizeof(eth_hdr)); }
|
||||||
IpHdr *h() { return (IpHdr *)(p->data + sizeof(eth_hdr)); }
|
IpHdr *h() { return (IpHdr *)(p->data + sizeof(eth_hdr)); }
|
||||||
|
|
||||||
void set(const PacketPtr &ptr)
|
void set(const EthPacketPtr &ptr)
|
||||||
{
|
{
|
||||||
EthHdr *eth = (EthHdr *)ptr->data;
|
EthHdr *eth = (EthHdr *)ptr->data;
|
||||||
if (eth->type() == ETH_TYPE_IP)
|
if (eth->type() == ETH_TYPE_IP)
|
||||||
|
@ -191,7 +191,7 @@ class IpPtr
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IpPtr() {}
|
IpPtr() {}
|
||||||
IpPtr(const PacketPtr &ptr) { set(ptr); }
|
IpPtr(const EthPacketPtr &ptr) { set(ptr); }
|
||||||
IpPtr(const EthPtr &ptr) { set(ptr.p); }
|
IpPtr(const EthPtr &ptr) { set(ptr.p); }
|
||||||
IpPtr(const IpPtr &ptr) : p(ptr.p) { }
|
IpPtr(const IpPtr &ptr) : p(ptr.p) { }
|
||||||
|
|
||||||
|
@ -203,12 +203,12 @@ class IpPtr
|
||||||
const IpHdr &operator*() const { return *h(); }
|
const IpHdr &operator*() const { return *h(); }
|
||||||
operator const IpHdr *() const { return h(); }
|
operator const IpHdr *() const { return h(); }
|
||||||
|
|
||||||
const IpPtr &operator=(const PacketPtr &ptr) { set(ptr); return *this; }
|
const IpPtr &operator=(const EthPacketPtr &ptr) { set(ptr); return *this; }
|
||||||
const IpPtr &operator=(const EthPtr &ptr) { set(ptr.p); return *this; }
|
const IpPtr &operator=(const EthPtr &ptr) { set(ptr.p); return *this; }
|
||||||
const IpPtr &operator=(const IpPtr &ptr) { p = ptr.p; return *this; }
|
const IpPtr &operator=(const IpPtr &ptr) { p = ptr.p; return *this; }
|
||||||
|
|
||||||
const PacketPtr packet() const { return p; }
|
const EthPacketPtr packet() const { return p; }
|
||||||
PacketPtr packet() { return p; }
|
EthPacketPtr packet() { return p; }
|
||||||
bool operator!() const { return !p; }
|
bool operator!() const { return !p; }
|
||||||
operator bool() const { return p; }
|
operator bool() const { return p; }
|
||||||
operator bool() { return p; }
|
operator bool() { return p; }
|
||||||
|
@ -272,13 +272,13 @@ struct TcpHdr : public tcp_hdr
|
||||||
class TcpPtr
|
class TcpPtr
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
PacketPtr p;
|
EthPacketPtr p;
|
||||||
int off;
|
int off;
|
||||||
|
|
||||||
const TcpHdr *h() const { return (const TcpHdr *)(p->data + off); }
|
const TcpHdr *h() const { return (const TcpHdr *)(p->data + off); }
|
||||||
TcpHdr *h() { return (TcpHdr *)(p->data + off); }
|
TcpHdr *h() { return (TcpHdr *)(p->data + off); }
|
||||||
|
|
||||||
void set(const PacketPtr &ptr, int offset) { p = ptr; off = offset; }
|
void set(const EthPacketPtr &ptr, int offset) { p = ptr; off = offset; }
|
||||||
void set(const IpPtr &ptr)
|
void set(const IpPtr &ptr)
|
||||||
{
|
{
|
||||||
if (ptr->proto() == IP_PROTO_TCP)
|
if (ptr->proto() == IP_PROTO_TCP)
|
||||||
|
@ -303,8 +303,8 @@ class TcpPtr
|
||||||
const TcpPtr &operator=(const IpPtr &i) { set(i); return *this; }
|
const TcpPtr &operator=(const IpPtr &i) { set(i); return *this; }
|
||||||
const TcpPtr &operator=(const TcpPtr &t) { set(t.p, t.off); return *this; }
|
const TcpPtr &operator=(const TcpPtr &t) { set(t.p, t.off); return *this; }
|
||||||
|
|
||||||
const PacketPtr packet() const { return p; }
|
const EthPacketPtr packet() const { return p; }
|
||||||
PacketPtr packet() { return p; }
|
EthPacketPtr packet() { return p; }
|
||||||
bool operator!() const { return !p; }
|
bool operator!() const { return !p; }
|
||||||
operator bool() const { return p; }
|
operator bool() const { return p; }
|
||||||
operator bool() { return p; }
|
operator bool() { return p; }
|
||||||
|
@ -362,13 +362,13 @@ struct UdpHdr : public udp_hdr
|
||||||
class UdpPtr
|
class UdpPtr
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
PacketPtr p;
|
EthPacketPtr p;
|
||||||
int off;
|
int off;
|
||||||
|
|
||||||
const UdpHdr *h() const { return (const UdpHdr *)(p->data + off); }
|
const UdpHdr *h() const { return (const UdpHdr *)(p->data + off); }
|
||||||
UdpHdr *h() { return (UdpHdr *)(p->data + off); }
|
UdpHdr *h() { return (UdpHdr *)(p->data + off); }
|
||||||
|
|
||||||
void set(const PacketPtr &ptr, int offset) { p = ptr; off = offset; }
|
void set(const EthPacketPtr &ptr, int offset) { p = ptr; off = offset; }
|
||||||
void set(const IpPtr &ptr)
|
void set(const IpPtr &ptr)
|
||||||
{
|
{
|
||||||
if (ptr->proto() == IP_PROTO_UDP)
|
if (ptr->proto() == IP_PROTO_UDP)
|
||||||
|
@ -393,8 +393,8 @@ class UdpPtr
|
||||||
const UdpPtr &operator=(const IpPtr &i) { set(i); return *this; }
|
const UdpPtr &operator=(const IpPtr &i) { set(i); return *this; }
|
||||||
const UdpPtr &operator=(const UdpPtr &t) { set(t.p, t.off); return *this; }
|
const UdpPtr &operator=(const UdpPtr &t) { set(t.p, t.off); return *this; }
|
||||||
|
|
||||||
const PacketPtr packet() const { return p; }
|
const EthPacketPtr packet() const { return p; }
|
||||||
PacketPtr packet() { return p; }
|
EthPacketPtr packet() { return p; }
|
||||||
bool operator!() const { return !p; }
|
bool operator!() const { return !p; }
|
||||||
operator bool() const { return p; }
|
operator bool() const { return p; }
|
||||||
operator bool() { return p; }
|
operator bool() { return p; }
|
||||||
|
|
32
configs/test/SysPaths.py
Normal file
32
configs/test/SysPaths.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
from m5 import *
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Edit the following list to include the possible paths to the binary
|
||||||
|
# and disk image directories. The first directory on the list that
|
||||||
|
# exists will be selected.
|
||||||
|
SYSTEMDIR_PATH = ['/n/poolfs/z/dist/m5/system']
|
||||||
|
|
||||||
|
SYSTEMDIR = None
|
||||||
|
for d in SYSTEMDIR_PATH:
|
||||||
|
if os.path.exists(d):
|
||||||
|
SYSTEMDIR = d
|
||||||
|
break
|
||||||
|
|
||||||
|
if not SYSTEMDIR:
|
||||||
|
print >>sys.stderr, "Can't find a path to system files."
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
BINDIR = SYSTEMDIR + '/binaries'
|
||||||
|
DISKDIR = SYSTEMDIR + '/disks'
|
||||||
|
|
||||||
|
def disk(file):
|
||||||
|
return '%s/%s' % (DISKDIR, file)
|
||||||
|
|
||||||
|
def binary(file):
|
||||||
|
return '%s/%s' % (BINDIR, file)
|
||||||
|
|
||||||
|
def script(file):
|
||||||
|
return '%s/%s' % ('/z/saidi/work/m5.newmem/configs/boot', file)
|
||||||
|
|
|
@ -30,6 +30,44 @@ class IdeControllerPciData(PciConfigData):
|
||||||
BAR3Size = '4B'
|
BAR3Size = '4B'
|
||||||
BAR4Size = '16B'
|
BAR4Size = '16B'
|
||||||
|
|
||||||
|
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 NSGigEPciData(PciConfigData):
|
||||||
|
VendorID = 0x100B
|
||||||
|
DeviceID = 0x0022
|
||||||
|
Status = 0x0290
|
||||||
|
SubClassCode = 0x00
|
||||||
|
ClassCode = 0x02
|
||||||
|
ProgIF = 0x00
|
||||||
|
BAR0 = 0x00000001
|
||||||
|
BAR1 = 0x00000000
|
||||||
|
BAR2 = 0x00000000
|
||||||
|
BAR3 = 0x00000000
|
||||||
|
BAR4 = 0x00000000
|
||||||
|
BAR5 = 0x00000000
|
||||||
|
MaximumLatency = 0x34
|
||||||
|
MinimumGrant = 0xb0
|
||||||
|
InterruptLine = 0x1e
|
||||||
|
InterruptPin = 0x01
|
||||||
|
BAR0Size = '256B'
|
||||||
|
BAR1Size = '4kB'
|
||||||
|
|
||||||
class LinuxRootDisk(IdeDisk):
|
class LinuxRootDisk(IdeDisk):
|
||||||
raw_image = RawDiskImage(image_file=linux_image, read_only=True)
|
raw_image = RawDiskImage(image_file=linux_image, read_only=True)
|
||||||
|
@ -77,9 +115,12 @@ class BaseTsunami(Tsunami):
|
||||||
fb = BadDevice(pio_addr=0x801fc0003d0, devicename='FrameBuffer')
|
fb = BadDevice(pio_addr=0x801fc0003d0, devicename='FrameBuffer')
|
||||||
io = TsunamiIO(pio_addr=0x801fc000000)
|
io = TsunamiIO(pio_addr=0x801fc000000)
|
||||||
uart = Uart8250(pio_addr=0x801fc0003f8)
|
uart = Uart8250(pio_addr=0x801fc0003f8)
|
||||||
# ethernet = NSGigE(configdata=NSGigEPciData(),
|
ethernet = NSGigE(configdata=NSGigEPciData(),
|
||||||
|
pci_bus=0, pci_dev=1, pci_func=0)
|
||||||
|
etherint = NSGigEInt(device=Parent.ethernet)
|
||||||
|
# ethernet = Sinic(configdata=SinicPciData(),
|
||||||
# pci_bus=0, pci_dev=1, pci_func=0)
|
# pci_bus=0, pci_dev=1, pci_func=0)
|
||||||
# etherint = NSGigEInt(device=Parent.ethernet)
|
# etherint = SinicInt(device=Parent.ethernet)
|
||||||
console = AlphaConsole(pio_addr=0x80200000000, disk=Parent.simple_disk)
|
console = AlphaConsole(pio_addr=0x80200000000, disk=Parent.simple_disk)
|
||||||
# bridge = PciFake(configdata=BridgePciData(), pci_bus=0, pci_dev=2, pci_func=0)
|
# bridge = PciFake(configdata=BridgePciData(), pci_bus=0, pci_dev=2, pci_func=0)
|
||||||
|
|
||||||
|
@ -106,6 +147,8 @@ class LinuxAlphaSystem(LinuxAlphaSystem):
|
||||||
c3 = Connector(side_a=Parent.tsunami.pchip, side_a_name='pio', side_b=Parent.magicbus)
|
c3 = Connector(side_a=Parent.tsunami.pchip, side_a_name='pio', side_b=Parent.magicbus)
|
||||||
c4 = Connector(side_a=Parent.tsunami.pciconfig, side_a_name='pio', side_b=Parent.magicbus)
|
c4 = Connector(side_a=Parent.tsunami.pciconfig, side_a_name='pio', side_b=Parent.magicbus)
|
||||||
c5 = Connector(side_a=Parent.tsunami.fake_sm_chip, side_a_name='pio', side_b=Parent.magicbus)
|
c5 = Connector(side_a=Parent.tsunami.fake_sm_chip, side_a_name='pio', side_b=Parent.magicbus)
|
||||||
|
c6 = Connector(side_a=Parent.tsunami.ethernet, side_a_name='pio', side_b=Parent.magicbus)
|
||||||
|
c6a = Connector(side_a=Parent.tsunami.ethernet, side_a_name='dma', side_b=Parent.magicbus)
|
||||||
c7 = Connector(side_a=Parent.tsunami.fake_uart1, side_a_name='pio', side_b=Parent.magicbus)
|
c7 = Connector(side_a=Parent.tsunami.fake_uart1, side_a_name='pio', side_b=Parent.magicbus)
|
||||||
c8 = Connector(side_a=Parent.tsunami.fake_uart2, side_a_name='pio', side_b=Parent.magicbus)
|
c8 = Connector(side_a=Parent.tsunami.fake_uart2, side_a_name='pio', side_b=Parent.magicbus)
|
||||||
c9 = Connector(side_a=Parent.tsunami.fake_uart3, side_a_name='pio', side_b=Parent.magicbus)
|
c9 = Connector(side_a=Parent.tsunami.fake_uart3, side_a_name='pio', side_b=Parent.magicbus)
|
||||||
|
@ -136,19 +179,33 @@ class LinuxAlphaSystem(LinuxAlphaSystem):
|
||||||
intrctrl = IntrControl()
|
intrctrl = IntrControl()
|
||||||
cpu = SimpleCPU(mem=Parent.magicbus)
|
cpu = SimpleCPU(mem=Parent.magicbus)
|
||||||
sim_console = SimConsole(listener=ConsoleListener(port=3456))
|
sim_console = SimConsole(listener=ConsoleListener(port=3456))
|
||||||
kernel = binary('vmlinux')
|
kernel = '/z/saidi/work/m5.newmem/build/vmlinux'
|
||||||
pal = binary('ts_osfpal')
|
pal = binary('ts_osfpal')
|
||||||
console = binary('console')
|
console = binary('console')
|
||||||
boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
||||||
readfile = os.path.join(test_base, 'halt.sh')
|
# readfile = os.path.join(test_base, 'halt.sh')
|
||||||
|
|
||||||
|
|
||||||
BaseCPU.itb = AlphaITB()
|
BaseCPU.itb = AlphaITB()
|
||||||
BaseCPU.dtb = AlphaDTB()
|
BaseCPU.dtb = AlphaDTB()
|
||||||
BaseCPU.system = Parent.any
|
BaseCPU.system = Parent.any
|
||||||
|
|
||||||
class TsunamiRoot(Root):
|
class TsunamiRoot(System):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
root = TsunamiRoot(clock = '2GHz', system = LinuxAlphaSystem())
|
def DualRoot(ClientSystem, ServerSystem):
|
||||||
|
self = Root()
|
||||||
|
self.client = ClientSystem()
|
||||||
|
self.server = ServerSystem()
|
||||||
|
|
||||||
|
self.etherdump = EtherDump(file='ethertrace')
|
||||||
|
self.etherlink = EtherLink(int1 = Parent.client.tsunami.etherint[0],
|
||||||
|
int2 = Parent.server.tsunami.etherint[0],
|
||||||
|
dump = Parent.etherdump)
|
||||||
|
self.clock = '5GHz'
|
||||||
|
return self
|
||||||
|
|
||||||
|
root = DualRoot(ClientSystem = LinuxAlphaSystem(readfile=script('netperf-stream-nt-client.rcS')),
|
||||||
|
ServerSystem = LinuxAlphaSystem(readfile=script('netperf-server.rcS')))
|
||||||
|
|
||||||
|
|
|
@ -310,7 +310,7 @@ CPUExecContext::getVirtPort(ExecContext *xc)
|
||||||
void
|
void
|
||||||
CPUExecContext::delVirtPort(VirtualPort *vp)
|
CPUExecContext::delVirtPort(VirtualPort *vp)
|
||||||
{
|
{
|
||||||
assert(!vp->nullExecContext());
|
// assert(!vp->nullExecContext());
|
||||||
delete vp->getPeer();
|
delete vp->getPeer();
|
||||||
delete vp;
|
delete vp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,21 +172,27 @@ SimpleCPU::SimpleCPU(Params *p)
|
||||||
#if SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE
|
#if SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE
|
||||||
ifetch_req = new Request(true);
|
ifetch_req = new Request(true);
|
||||||
ifetch_req->setAsid(0);
|
ifetch_req->setAsid(0);
|
||||||
|
// @todo fix me and get the real cpu iD!!!
|
||||||
|
ifetch_req->setCpuNum(0);
|
||||||
ifetch_req->setSize(sizeof(MachInst));
|
ifetch_req->setSize(sizeof(MachInst));
|
||||||
ifetch_pkt = new Packet;
|
ifetch_pkt = new Packet;
|
||||||
ifetch_pkt->cmd = Read;
|
ifetch_pkt->cmd = Read;
|
||||||
ifetch_pkt->data = (uint8_t *)&inst;
|
ifetch_pkt->dataStatic(&inst);
|
||||||
ifetch_pkt->req = ifetch_req;
|
ifetch_pkt->req = ifetch_req;
|
||||||
ifetch_pkt->size = sizeof(MachInst);
|
ifetch_pkt->size = sizeof(MachInst);
|
||||||
|
|
||||||
data_read_req = new Request(true);
|
data_read_req = new Request(true);
|
||||||
|
// @todo fix me and get the real cpu iD!!!
|
||||||
|
data_read_req->setCpuNum(0);
|
||||||
data_read_req->setAsid(0);
|
data_read_req->setAsid(0);
|
||||||
data_read_pkt = new Packet;
|
data_read_pkt = new Packet;
|
||||||
data_read_pkt->cmd = Read;
|
data_read_pkt->cmd = Read;
|
||||||
data_read_pkt->data = new uint8_t[8];
|
data_read_pkt->dataStatic(&dataReg);
|
||||||
data_read_pkt->req = data_read_req;
|
data_read_pkt->req = data_read_req;
|
||||||
|
|
||||||
data_write_req = new Request(true);
|
data_write_req = new Request(true);
|
||||||
|
// @todo fix me and get the real cpu iD!!!
|
||||||
|
data_write_req->setCpuNum(0);
|
||||||
data_write_req->setAsid(0);
|
data_write_req->setAsid(0);
|
||||||
data_write_pkt = new Packet;
|
data_write_pkt = new Packet;
|
||||||
data_write_pkt->cmd = Write;
|
data_write_pkt->cmd = Write;
|
||||||
|
@ -474,7 +480,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
|
||||||
// Fault fault = xc->read(memReq,data);
|
// Fault fault = xc->read(memReq,data);
|
||||||
// Not sure what to check for no fault...
|
// Not sure what to check for no fault...
|
||||||
if (data_read_pkt->result == Success) {
|
if (data_read_pkt->result == Success) {
|
||||||
memcpy(&data, data_read_pkt->data, sizeof(T));
|
data = data_read_pkt->get<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (traceData) {
|
if (traceData) {
|
||||||
|
@ -517,7 +523,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
|
||||||
// Need to find a way to not duplicate code above.
|
// Need to find a way to not duplicate code above.
|
||||||
|
|
||||||
if (data_read_pkt->result == Success) {
|
if (data_read_pkt->result == Success) {
|
||||||
memcpy(&data, data_read_pkt->data, sizeof(T));
|
data = data_read_pkt->get<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (traceData) {
|
if (traceData) {
|
||||||
|
@ -621,11 +627,11 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
|
||||||
data_write_pkt = new Packet;
|
data_write_pkt = new Packet;
|
||||||
data_write_pkt->cmd = Write;
|
data_write_pkt->cmd = Write;
|
||||||
data_write_pkt->req = data_write_req;
|
data_write_pkt->req = data_write_req;
|
||||||
data_write_pkt->data = new uint8_t[64];
|
data_write_pkt->allocate();
|
||||||
memcpy(data_write_pkt->data, &data, sizeof(T));
|
data_write_pkt->set(data);
|
||||||
#else
|
#else
|
||||||
data_write_pkt->reset();
|
data_write_pkt->reset();
|
||||||
data_write_pkt->data = (uint8_t *)&data;
|
data_write_pkt->dataStatic(&data);
|
||||||
#endif
|
#endif
|
||||||
data_write_pkt->addr = data_write_req->getPaddr();
|
data_write_pkt->addr = data_write_req->getPaddr();
|
||||||
data_write_pkt->size = sizeof(T);
|
data_write_pkt->size = sizeof(T);
|
||||||
|
@ -816,7 +822,7 @@ SimpleCPU::processResponse(Packet &response)
|
||||||
scheduleTickEvent(1);
|
scheduleTickEvent(1);
|
||||||
|
|
||||||
// Copy the icache data into the instruction itself.
|
// Copy the icache data into the instruction itself.
|
||||||
memcpy(&inst, pkt->data, sizeof(inst));
|
inst = pkt->get<MachInst>();
|
||||||
|
|
||||||
delete pkt;
|
delete pkt;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -207,6 +207,9 @@ class SimpleCPU : public BaseCPU
|
||||||
// current instruction
|
// current instruction
|
||||||
MachInst inst;
|
MachInst inst;
|
||||||
|
|
||||||
|
// Static data storage
|
||||||
|
TheISA::IntReg dataReg;
|
||||||
|
|
||||||
#if SIMPLE_CPU_MEM_TIMING
|
#if SIMPLE_CPU_MEM_TIMING
|
||||||
Packet *retry_pkt;
|
Packet *retry_pkt;
|
||||||
#elif SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE
|
#elif SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE
|
||||||
|
|
|
@ -102,31 +102,24 @@ AlphaConsole::read(Packet &pkt)
|
||||||
pkt.time = curTick + pioDelay;
|
pkt.time = curTick + pioDelay;
|
||||||
Addr daddr = pkt.addr - pioAddr;
|
Addr daddr = pkt.addr - pioAddr;
|
||||||
|
|
||||||
uint32_t *data32;
|
pkt.allocate();
|
||||||
uint64_t *data64;
|
|
||||||
|
|
||||||
switch (pkt.size)
|
switch (pkt.size)
|
||||||
{
|
{
|
||||||
case sizeof(uint32_t):
|
case sizeof(uint32_t):
|
||||||
if (!pkt.data) {
|
|
||||||
data32 = new uint32_t;
|
|
||||||
pkt.data = (uint8_t*)data32;
|
|
||||||
} else
|
|
||||||
data32 = (uint32_t*)pkt.data;
|
|
||||||
|
|
||||||
switch (daddr)
|
switch (daddr)
|
||||||
{
|
{
|
||||||
case offsetof(AlphaAccess, last_offset):
|
case offsetof(AlphaAccess, last_offset):
|
||||||
*data32 = alphaAccess->last_offset;
|
pkt.set(alphaAccess->last_offset);
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, version):
|
case offsetof(AlphaAccess, version):
|
||||||
*data32 = alphaAccess->version;
|
pkt.set(alphaAccess->version);
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, numCPUs):
|
case offsetof(AlphaAccess, numCPUs):
|
||||||
*data32 = alphaAccess->numCPUs;
|
pkt.set(alphaAccess->numCPUs);
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, intrClockFrequency):
|
case offsetof(AlphaAccess, intrClockFrequency):
|
||||||
*data32 = alphaAccess->intrClockFrequency;
|
pkt.set(alphaAccess->intrClockFrequency);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Old console code read in everyting as a 32bit int
|
/* Old console code read in everyting as a 32bit int
|
||||||
|
@ -134,62 +127,59 @@ AlphaConsole::read(Packet &pkt)
|
||||||
*/
|
*/
|
||||||
pkt.result = BadAddress;
|
pkt.result = BadAddress;
|
||||||
}
|
}
|
||||||
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *data32);
|
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr,
|
||||||
|
pkt.get<uint32_t>());
|
||||||
break;
|
break;
|
||||||
case sizeof(uint64_t):
|
case sizeof(uint64_t):
|
||||||
if (!pkt.data) {
|
|
||||||
data64 = new uint64_t;
|
|
||||||
pkt.data = (uint8_t*)data64;
|
|
||||||
} else
|
|
||||||
data64 = (uint64_t*)pkt.data;
|
|
||||||
switch (daddr)
|
switch (daddr)
|
||||||
{
|
{
|
||||||
case offsetof(AlphaAccess, inputChar):
|
case offsetof(AlphaAccess, inputChar):
|
||||||
*data64 = console->console_in();
|
pkt.set(console->console_in());
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, cpuClock):
|
case offsetof(AlphaAccess, cpuClock):
|
||||||
*data64 = alphaAccess->cpuClock;
|
pkt.set(alphaAccess->cpuClock);
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, mem_size):
|
case offsetof(AlphaAccess, mem_size):
|
||||||
*data64 = alphaAccess->mem_size;
|
pkt.set(alphaAccess->mem_size);
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, kernStart):
|
case offsetof(AlphaAccess, kernStart):
|
||||||
*data64 = alphaAccess->kernStart;
|
pkt.set(alphaAccess->kernStart);
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, kernEnd):
|
case offsetof(AlphaAccess, kernEnd):
|
||||||
*data64 = alphaAccess->kernEnd;
|
pkt.set(alphaAccess->kernEnd);
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, entryPoint):
|
case offsetof(AlphaAccess, entryPoint):
|
||||||
*data64 = alphaAccess->entryPoint;
|
pkt.set(alphaAccess->entryPoint);
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, diskUnit):
|
case offsetof(AlphaAccess, diskUnit):
|
||||||
*data64 = alphaAccess->diskUnit;
|
pkt.set(alphaAccess->diskUnit);
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, diskCount):
|
case offsetof(AlphaAccess, diskCount):
|
||||||
*data64 = alphaAccess->diskCount;
|
pkt.set(alphaAccess->diskCount);
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, diskPAddr):
|
case offsetof(AlphaAccess, diskPAddr):
|
||||||
*data64 = alphaAccess->diskPAddr;
|
pkt.set(alphaAccess->diskPAddr);
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, diskBlock):
|
case offsetof(AlphaAccess, diskBlock):
|
||||||
*data64 = alphaAccess->diskBlock;
|
pkt.set(alphaAccess->diskBlock);
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, diskOperation):
|
case offsetof(AlphaAccess, diskOperation):
|
||||||
*data64 = alphaAccess->diskOperation;
|
pkt.set(alphaAccess->diskOperation);
|
||||||
break;
|
break;
|
||||||
case offsetof(AlphaAccess, outputChar):
|
case offsetof(AlphaAccess, outputChar):
|
||||||
*data64 = alphaAccess->outputChar;
|
pkt.set(alphaAccess->outputChar);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
|
int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
|
||||||
sizeof(alphaAccess->cpuStack[0]);
|
sizeof(alphaAccess->cpuStack[0]);
|
||||||
|
|
||||||
if (cpunum >= 0 && cpunum < 64)
|
if (cpunum >= 0 && cpunum < 64)
|
||||||
*data64 = alphaAccess->cpuStack[cpunum];
|
pkt.set(alphaAccess->cpuStack[cpunum]);
|
||||||
else
|
else
|
||||||
panic("Unknown 64bit access, %#x\n", daddr);
|
panic("Unknown 64bit access, %#x\n", daddr);
|
||||||
}
|
}
|
||||||
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *data64);
|
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr,
|
||||||
|
pkt.get<uint64_t>());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pkt.result = BadAddress;
|
pkt.result = BadAddress;
|
||||||
|
@ -207,7 +197,7 @@ AlphaConsole::write(Packet &pkt)
|
||||||
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
||||||
Addr daddr = pkt.addr - pioAddr;
|
Addr daddr = pkt.addr - pioAddr;
|
||||||
|
|
||||||
uint64_t val = *(uint64_t *)pkt.data;
|
uint64_t val = pkt.get<uint64_t>();
|
||||||
assert(pkt.size == sizeof(uint64_t));
|
assert(pkt.size == sizeof(uint64_t));
|
||||||
|
|
||||||
switch (daddr) {
|
switch (daddr) {
|
||||||
|
|
|
@ -81,7 +81,7 @@ EtherBus::reg(EtherInt *dev)
|
||||||
{ devlist.push_back(dev); }
|
{ devlist.push_back(dev); }
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EtherBus::send(EtherInt *sndr, PacketPtr &pkt)
|
EtherBus::send(EtherInt *sndr, EthPacketPtr &pkt)
|
||||||
{
|
{
|
||||||
if (busy()) {
|
if (busy()) {
|
||||||
DPRINTF(Ethernet, "ethernet packet not sent, bus busy\n", curTick);
|
DPRINTF(Ethernet, "ethernet packet not sent, bus busy\n", curTick);
|
||||||
|
|
|
@ -61,7 +61,7 @@ class EtherBus : public SimObject
|
||||||
};
|
};
|
||||||
|
|
||||||
DoneEvent event;
|
DoneEvent event;
|
||||||
PacketPtr packet;
|
EthPacketPtr packet;
|
||||||
EtherInt *sender;
|
EtherInt *sender;
|
||||||
EtherDump *dump;
|
EtherDump *dump;
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ class EtherBus : public SimObject
|
||||||
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, PacketPtr &packet);
|
bool send(EtherInt *sender, EthPacketPtr &packet);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ETHERBUS_H__
|
#endif // __ETHERBUS_H__
|
||||||
|
|
|
@ -102,7 +102,7 @@ EtherDump::init()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
EtherDump::dumpPacket(PacketPtr &packet)
|
EtherDump::dumpPacket(EthPacketPtr &packet)
|
||||||
{
|
{
|
||||||
pcap_pkthdr pkthdr;
|
pcap_pkthdr pkthdr;
|
||||||
pkthdr.seconds = curtime + (curTick / Clock::Int::s);
|
pkthdr.seconds = curtime + (curTick / Clock::Int::s);
|
||||||
|
|
|
@ -45,7 +45,7 @@ class EtherDump : public SimObject
|
||||||
private:
|
private:
|
||||||
std::ofstream stream;
|
std::ofstream stream;
|
||||||
const int maxlen;
|
const int maxlen;
|
||||||
void dumpPacket(PacketPtr &packet);
|
void dumpPacket(EthPacketPtr &packet);
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
Tick curtime;
|
Tick curtime;
|
||||||
|
@ -53,7 +53,7 @@ class EtherDump : public SimObject
|
||||||
public:
|
public:
|
||||||
EtherDump(const std::string &name, const std::string &file, int max);
|
EtherDump(const std::string &name, const std::string &file, int max);
|
||||||
|
|
||||||
inline void dump(PacketPtr &pkt) { dumpPacket(pkt); }
|
inline void dump(EthPacketPtr &pkt) { dumpPacket(pkt); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ETHERDUMP_H__
|
#endif // __ETHERDUMP_H__
|
||||||
|
|
|
@ -58,9 +58,9 @@ class EtherInt : public SimObject
|
||||||
void recvDone() { peer->sendDone(); }
|
void recvDone() { peer->sendDone(); }
|
||||||
virtual void sendDone() = 0;
|
virtual void sendDone() = 0;
|
||||||
|
|
||||||
bool sendPacket(PacketPtr packet)
|
bool sendPacket(EthPacketPtr packet)
|
||||||
{ return peer ? peer->recvPacket(packet) : true; }
|
{ return peer ? peer->recvPacket(packet) : true; }
|
||||||
virtual bool recvPacket(PacketPtr packet) = 0;
|
virtual bool recvPacket(EthPacketPtr packet) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __DEV_ETHERINT_HH__
|
#endif // __DEV_ETHERINT_HH__
|
||||||
|
|
|
@ -102,7 +102,7 @@ EtherLink::unserialize(Checkpoint *cp, const string §ion)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
EtherLink::Link::txComplete(PacketPtr packet)
|
EtherLink::Link::txComplete(EthPacketPtr packet)
|
||||||
{
|
{
|
||||||
DPRINTF(Ethernet, "packet received: len=%d\n", packet->length);
|
DPRINTF(Ethernet, "packet received: len=%d\n", packet->length);
|
||||||
DDUMP(EthernetData, packet->data, packet->length);
|
DDUMP(EthernetData, packet->data, packet->length);
|
||||||
|
@ -113,12 +113,12 @@ class LinkDelayEvent : public Event
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
EtherLink::Link *link;
|
EtherLink::Link *link;
|
||||||
PacketPtr packet;
|
EthPacketPtr packet;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// non-scheduling version for createForUnserialize()
|
// non-scheduling version for createForUnserialize()
|
||||||
LinkDelayEvent();
|
LinkDelayEvent();
|
||||||
LinkDelayEvent(EtherLink::Link *link, PacketPtr pkt, Tick when);
|
LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt, Tick when);
|
||||||
|
|
||||||
void process();
|
void process();
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ EtherLink::Link::txDone()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EtherLink::Link::transmit(PacketPtr pkt)
|
EtherLink::Link::transmit(EthPacketPtr pkt)
|
||||||
{
|
{
|
||||||
if (busy()) {
|
if (busy()) {
|
||||||
DPRINTF(Ethernet, "packet not sent, link busy\n");
|
DPRINTF(Ethernet, "packet not sent, link busy\n");
|
||||||
|
@ -195,7 +195,7 @@ EtherLink::Link::unserialize(const string &base, Checkpoint *cp,
|
||||||
bool packet_exists;
|
bool packet_exists;
|
||||||
paramIn(cp, section, base + ".packet_exists", packet_exists);
|
paramIn(cp, section, base + ".packet_exists", packet_exists);
|
||||||
if (packet_exists) {
|
if (packet_exists) {
|
||||||
packet = new PacketData(16384);
|
packet = new EthPacketData(16384);
|
||||||
packet->unserialize(base + ".packet", cp, section);
|
packet->unserialize(base + ".packet", cp, section);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ LinkDelayEvent::LinkDelayEvent()
|
||||||
setFlags(AutoDelete);
|
setFlags(AutoDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, PacketPtr p, Tick when)
|
LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, EthPacketPtr p, Tick when)
|
||||||
: Event(&mainEventQueue), link(l), packet(p)
|
: Event(&mainEventQueue), link(l), packet(p)
|
||||||
{
|
{
|
||||||
setFlags(AutoSerialize);
|
setFlags(AutoSerialize);
|
||||||
|
@ -256,7 +256,7 @@ LinkDelayEvent::unserialize(Checkpoint *cp, const string §ion)
|
||||||
|
|
||||||
link = parent->link[number];
|
link = parent->link[number];
|
||||||
|
|
||||||
packet = new PacketData(16384);
|
packet = new EthPacketData(16384);
|
||||||
packet->unserialize("packet", cp, section);
|
packet->unserialize("packet", cp, section);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,14 +73,14 @@ class EtherLink : public SimObject
|
||||||
/*
|
/*
|
||||||
* Transfer is complete
|
* Transfer is complete
|
||||||
*/
|
*/
|
||||||
PacketPtr packet;
|
EthPacketPtr packet;
|
||||||
void txDone();
|
void txDone();
|
||||||
typedef EventWrapper<Link, &Link::txDone> DoneEvent;
|
typedef EventWrapper<Link, &Link::txDone> DoneEvent;
|
||||||
friend void DoneEvent::process();
|
friend void DoneEvent::process();
|
||||||
DoneEvent doneEvent;
|
DoneEvent doneEvent;
|
||||||
|
|
||||||
friend class LinkDelayEvent;
|
friend class LinkDelayEvent;
|
||||||
void txComplete(PacketPtr packet);
|
void txComplete(EthPacketPtr packet);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Link(const std::string &name, EtherLink *p, int num,
|
Link(const std::string &name, EtherLink *p, int num,
|
||||||
|
@ -90,7 +90,7 @@ class EtherLink : public SimObject
|
||||||
const std::string name() const { return objName; }
|
const std::string name() const { return objName; }
|
||||||
|
|
||||||
bool busy() const { return (bool)packet; }
|
bool busy() const { return (bool)packet; }
|
||||||
bool transmit(PacketPtr packet);
|
bool transmit(EthPacketPtr packet);
|
||||||
|
|
||||||
void setTxInt(Interface *i) { assert(!txint); txint = i; }
|
void setTxInt(Interface *i) { assert(!txint); txint = i; }
|
||||||
void setRxInt(Interface *i) { assert(!rxint); rxint = i; }
|
void setRxInt(Interface *i) { assert(!rxint); rxint = i; }
|
||||||
|
@ -110,7 +110,7 @@ class EtherLink : public SimObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Interface(const std::string &name, Link *txlink, Link *rxlink);
|
Interface(const std::string &name, Link *txlink, Link *rxlink);
|
||||||
bool recvPacket(PacketPtr packet) { return txlink->transmit(packet); }
|
bool recvPacket(EthPacketPtr packet) { return txlink->transmit(packet); }
|
||||||
void sendDone() { peer->sendDone(); }
|
void sendDone() { peer->sendDone(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void
|
void
|
||||||
PacketData::serialize(const string &base, ostream &os)
|
EthPacketData::serialize(const string &base, ostream &os)
|
||||||
{
|
{
|
||||||
paramOut(os, base + ".length", length);
|
paramOut(os, base + ".length", length);
|
||||||
paramOut(os, base + ".slack", slack);
|
paramOut(os, base + ".slack", slack);
|
||||||
|
@ -43,7 +43,7 @@ PacketData::serialize(const string &base, ostream &os)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PacketData::unserialize(const string &base, Checkpoint *cp,
|
EthPacketData::unserialize(const string &base, Checkpoint *cp,
|
||||||
const string §ion)
|
const string §ion)
|
||||||
{
|
{
|
||||||
paramIn(cp, section, base + ".length", length);
|
paramIn(cp, section, base + ".length", length);
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
* Reference counted class containing ethernet packet data
|
* Reference counted class containing ethernet packet data
|
||||||
*/
|
*/
|
||||||
class Checkpoint;
|
class Checkpoint;
|
||||||
class PacketData : public RefCounted
|
class EthPacketData : public RefCounted
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*
|
/*
|
||||||
|
@ -66,12 +66,12 @@ class PacketData : public RefCounted
|
||||||
int slack;
|
int slack;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PacketData() : data(NULL), length(0), slack(0) { }
|
EthPacketData() : data(NULL), length(0), slack(0) { }
|
||||||
explicit PacketData(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) { }
|
||||||
PacketData(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) { }
|
||||||
~PacketData() { if (data) delete [] data; }
|
~EthPacketData() { if (data) delete [] data; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void serialize(const std::string &base, std::ostream &os);
|
void serialize(const std::string &base, std::ostream &os);
|
||||||
|
@ -79,6 +79,6 @@ class PacketData : public RefCounted
|
||||||
const std::string §ion);
|
const std::string §ion);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef RefCountingPtr<PacketData> PacketPtr;
|
typedef RefCountingPtr<EthPacketData> EthPacketPtr;
|
||||||
|
|
||||||
#endif // __ETHERPKT_HH__
|
#endif // __ETHERPKT_HH__
|
||||||
|
|
|
@ -169,7 +169,7 @@ EtherTap::detach()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EtherTap::recvPacket(PacketPtr packet)
|
EtherTap::recvPacket(EthPacketPtr packet)
|
||||||
{
|
{
|
||||||
if (dump)
|
if (dump)
|
||||||
dump->dump(packet);
|
dump->dump(packet);
|
||||||
|
@ -218,8 +218,8 @@ EtherTap::process(int revent)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (data_len != 0 && buffer_offset >= data_len + sizeof(u_int32_t)) {
|
while (data_len != 0 && buffer_offset >= data_len + sizeof(u_int32_t)) {
|
||||||
PacketPtr packet;
|
EthPacketPtr packet;
|
||||||
packet = new PacketData(data_len);
|
packet = new EthPacketData(data_len);
|
||||||
packet->length = data_len;
|
packet->length = data_len;
|
||||||
memcpy(packet->data, data, data_len);
|
memcpy(packet->data, data, data_len);
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ EtherTap::retransmit()
|
||||||
if (packetBuffer.empty())
|
if (packetBuffer.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PacketPtr packet = packetBuffer.front();
|
EthPacketPtr packet = packetBuffer.front();
|
||||||
if (sendPacket(packet)) {
|
if (sendPacket(packet)) {
|
||||||
if (dump)
|
if (dump)
|
||||||
dump->dump(packet);
|
dump->dump(packet);
|
||||||
|
|
|
@ -70,10 +70,10 @@ class EtherTap : public EtherInt
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string device;
|
std::string device;
|
||||||
std::queue<PacketPtr> packetBuffer;
|
std::queue<EthPacketPtr> packetBuffer;
|
||||||
|
|
||||||
void process(int revent);
|
void process(int revent);
|
||||||
void enqueue(PacketData *packet);
|
void enqueue(EthPacketData *packet);
|
||||||
void retransmit();
|
void retransmit();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -97,7 +97,7 @@ class EtherTap : public EtherInt
|
||||||
EtherTap(const std::string &name, EtherDump *dump, int port, int bufsz);
|
EtherTap(const std::string &name, EtherDump *dump, int port, int bufsz);
|
||||||
virtual ~EtherTap();
|
virtual ~EtherTap();
|
||||||
|
|
||||||
virtual bool recvPacket(PacketPtr packet);
|
virtual bool recvPacket(EthPacketPtr packet);
|
||||||
virtual void sendDone();
|
virtual void sendDone();
|
||||||
|
|
||||||
virtual void serialize(std::ostream &os);
|
virtual void serialize(std::ostream &os);
|
||||||
|
|
|
@ -430,38 +430,10 @@ IdeController::read(Packet &pkt)
|
||||||
IdeRegType reg_type;
|
IdeRegType reg_type;
|
||||||
int disk;
|
int disk;
|
||||||
|
|
||||||
uint8_t *data8 = 0 ;
|
pkt.time = curTick + pioDelay;
|
||||||
uint16_t *data16 = 0;
|
pkt.allocate();
|
||||||
uint32_t *data32 = 0;
|
if (pkt.size != 1 && pkt.size != 2 && pkt.size !=4)
|
||||||
|
|
||||||
switch(pkt.size) {
|
|
||||||
case sizeof(uint8_t):
|
|
||||||
if (!pkt.data) {
|
|
||||||
data8 = new uint8_t;
|
|
||||||
pkt.data = data8;
|
|
||||||
} else
|
|
||||||
data8 = pkt.data;
|
|
||||||
*data8 = 0;
|
|
||||||
break;
|
|
||||||
case sizeof(uint16_t):
|
|
||||||
if (!pkt.data) {
|
|
||||||
data16 = new uint16_t;
|
|
||||||
pkt.data = (uint8_t*)data16;
|
|
||||||
} else
|
|
||||||
data16 = (uint16_t*)pkt.data;
|
|
||||||
*data16 = 0;
|
|
||||||
break;
|
|
||||||
case sizeof(uint32_t):
|
|
||||||
if (!pkt.data) {
|
|
||||||
data32 = new uint32_t;
|
|
||||||
pkt.data = (uint8_t*)data32;
|
|
||||||
} else
|
|
||||||
data32 = (uint32_t*)pkt.data;
|
|
||||||
*data32 = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
panic("Bad IDE read size: %d\n", pkt.size);
|
panic("Bad IDE read size: %d\n", pkt.size);
|
||||||
}
|
|
||||||
|
|
||||||
parseAddr(pkt.addr, offset, channel, reg_type);
|
parseAddr(pkt.addr, offset, channel, reg_type);
|
||||||
|
|
||||||
|
@ -474,13 +446,13 @@ IdeController::read(Packet &pkt)
|
||||||
case BMI_BLOCK:
|
case BMI_BLOCK:
|
||||||
switch (pkt.size) {
|
switch (pkt.size) {
|
||||||
case sizeof(uint8_t):
|
case sizeof(uint8_t):
|
||||||
*data8 = bmi_regs.data[offset];
|
pkt.set(bmi_regs.data[offset]);
|
||||||
break;
|
break;
|
||||||
case sizeof(uint16_t):
|
case sizeof(uint16_t):
|
||||||
*data16 = *(uint16_t*)&bmi_regs.data[offset];
|
pkt.set(*(uint16_t*)&bmi_regs.data[offset]);
|
||||||
break;
|
break;
|
||||||
case sizeof(uint32_t):
|
case sizeof(uint32_t):
|
||||||
*data32 = *(uint32_t*)&bmi_regs.data[offset];
|
pkt.set(*(uint32_t*)&bmi_regs.data[offset]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("IDE read of BMI reg invalid size: %#x\n", pkt.size);
|
panic("IDE read of BMI reg invalid size: %#x\n", pkt.size);
|
||||||
|
@ -491,19 +463,22 @@ IdeController::read(Packet &pkt)
|
||||||
case CONTROL_BLOCK:
|
case CONTROL_BLOCK:
|
||||||
disk = getDisk(channel);
|
disk = getDisk(channel);
|
||||||
|
|
||||||
if (disks[disk] == NULL)
|
if (disks[disk] == NULL) {
|
||||||
|
pkt.set<uint8_t>(0);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch (offset) {
|
switch (offset) {
|
||||||
case DATA_OFFSET:
|
case DATA_OFFSET:
|
||||||
switch (pkt.size) {
|
switch (pkt.size) {
|
||||||
case sizeof(uint16_t):
|
case sizeof(uint16_t):
|
||||||
disks[disk]->read(offset, reg_type, (uint8_t*)data16);
|
disks[disk]->read(offset, reg_type, pkt.getPtr<uint8_t>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sizeof(uint32_t):
|
case sizeof(uint32_t):
|
||||||
disks[disk]->read(offset, reg_type, (uint8_t*)data16);
|
disks[disk]->read(offset, reg_type, pkt.getPtr<uint8_t>());
|
||||||
disks[disk]->read(offset, reg_type, (uint8_t*)(data16 + sizeof(uint16_t)));
|
disks[disk]->read(offset, reg_type,
|
||||||
|
pkt.getPtr<uint8_t>() + sizeof(uint16_t));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -512,7 +487,7 @@ IdeController::read(Packet &pkt)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (pkt.size == sizeof(uint8_t)) {
|
if (pkt.size == sizeof(uint8_t)) {
|
||||||
disks[disk]->read(offset, reg_type, data8);
|
disks[disk]->read(offset, reg_type, pkt.getPtr<uint8_t>());
|
||||||
} else
|
} else
|
||||||
panic("IDE read of command reg of invalid size: %#x\n", pkt.size);
|
panic("IDE read of command reg of invalid size: %#x\n", pkt.size);
|
||||||
}
|
}
|
||||||
|
@ -522,13 +497,13 @@ IdeController::read(Packet &pkt)
|
||||||
}
|
}
|
||||||
if (pkt.size == 1)
|
if (pkt.size == 1)
|
||||||
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
|
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
|
||||||
offset, pkt.size, (uint32_t)*data8);
|
offset, pkt.size, (uint32_t)pkt.get<uint8_t>());
|
||||||
else if (pkt.size == 2)
|
else if (pkt.size == 2)
|
||||||
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
|
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
|
||||||
offset, pkt.size, *data16);
|
offset, pkt.size, pkt.get<uint16_t>());
|
||||||
else
|
else
|
||||||
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
|
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
|
||||||
offset, pkt.size, *data32);
|
offset, pkt.size, pkt.get<uint32_t>());
|
||||||
|
|
||||||
pkt.result = Success;
|
pkt.result = Success;
|
||||||
return pioDelay;
|
return pioDelay;
|
||||||
|
@ -542,14 +517,14 @@ IdeController::write(Packet &pkt)
|
||||||
IdeRegType reg_type;
|
IdeRegType reg_type;
|
||||||
int disk;
|
int disk;
|
||||||
uint8_t oldVal, newVal;
|
uint8_t oldVal, newVal;
|
||||||
uint8_t data8 = *(uint8_t*)pkt.data;
|
|
||||||
uint32_t data32 = *(uint32_t*)pkt.data;
|
|
||||||
|
|
||||||
|
pkt.time = curTick + pioDelay;
|
||||||
|
|
||||||
parseAddr(pkt.addr, offset, channel, reg_type);
|
parseAddr(pkt.addr, offset, channel, reg_type);
|
||||||
|
|
||||||
if (!io_enabled) {
|
if (!io_enabled) {
|
||||||
pkt.result = Success;
|
pkt.result = Success;
|
||||||
|
DPRINTF(IdeCtrl, "io not enabled\n");
|
||||||
return pioDelay;
|
return pioDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +546,7 @@ IdeController::write(Packet &pkt)
|
||||||
disk = getDisk(channel);
|
disk = getDisk(channel);
|
||||||
|
|
||||||
oldVal = bmi_regs.chan[channel].bmic;
|
oldVal = bmi_regs.chan[channel].bmic;
|
||||||
newVal = data8;
|
newVal = pkt.get<uint8_t>();
|
||||||
|
|
||||||
// if a DMA transfer is in progress, R/W control cannot change
|
// if a DMA transfer is in progress, R/W control cannot change
|
||||||
if (oldVal & SSBM) {
|
if (oldVal & SSBM) {
|
||||||
|
@ -624,7 +599,7 @@ IdeController::write(Packet &pkt)
|
||||||
panic("Invalid BMIS write size: %x\n", pkt.size);
|
panic("Invalid BMIS write size: %x\n", pkt.size);
|
||||||
|
|
||||||
oldVal = bmi_regs.chan[channel].bmis;
|
oldVal = bmi_regs.chan[channel].bmis;
|
||||||
newVal = data8;
|
newVal = pkt.get<uint8_t>();
|
||||||
|
|
||||||
// the BMIDEA bit is RO
|
// the BMIDEA bit is RO
|
||||||
newVal |= (oldVal & BMIDEA);
|
newVal |= (oldVal & BMIDEA);
|
||||||
|
@ -650,7 +625,7 @@ IdeController::write(Packet &pkt)
|
||||||
if (pkt.size != sizeof(uint32_t))
|
if (pkt.size != sizeof(uint32_t))
|
||||||
panic("Invalid BMIDTP write size: %x\n", pkt.size);
|
panic("Invalid BMIDTP write size: %x\n", pkt.size);
|
||||||
|
|
||||||
bmi_regs.chan[channel].bmidtp = htole(data32 & ~0x3);
|
bmi_regs.chan[channel].bmidtp = htole(pkt.get<uint32_t>() & ~0x3);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -662,13 +637,13 @@ IdeController::write(Packet &pkt)
|
||||||
pkt.size);
|
pkt.size);
|
||||||
|
|
||||||
// do a default copy of data into the registers
|
// do a default copy of data into the registers
|
||||||
memcpy(&bmi_regs.data[offset], pkt.data, pkt.size);
|
memcpy(&bmi_regs.data[offset], pkt.getPtr<uint8_t>(), pkt.size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case COMMAND_BLOCK:
|
case COMMAND_BLOCK:
|
||||||
if (offset == IDE_SELECT_OFFSET) {
|
if (offset == IDE_SELECT_OFFSET) {
|
||||||
uint8_t *devBit = &dev[channel];
|
uint8_t *devBit = &dev[channel];
|
||||||
*devBit = (letoh(data8) & IDE_SELECT_DEV_BIT) ? 1 : 0;
|
*devBit = (letoh(pkt.get<uint8_t>()) & IDE_SELECT_DEV_BIT) ? 1 : 0;
|
||||||
}
|
}
|
||||||
// fall-through ok!
|
// fall-through ok!
|
||||||
case CONTROL_BLOCK:
|
case CONTROL_BLOCK:
|
||||||
|
@ -681,12 +656,12 @@ IdeController::write(Packet &pkt)
|
||||||
case DATA_OFFSET:
|
case DATA_OFFSET:
|
||||||
switch (pkt.size) {
|
switch (pkt.size) {
|
||||||
case sizeof(uint16_t):
|
case sizeof(uint16_t):
|
||||||
disks[disk]->write(offset, reg_type, pkt.data);
|
disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sizeof(uint32_t):
|
case sizeof(uint32_t):
|
||||||
disks[disk]->write(offset, reg_type, pkt.data);
|
disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>());
|
||||||
disks[disk]->write(offset, reg_type, pkt.data +
|
disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>() +
|
||||||
sizeof(uint16_t));
|
sizeof(uint16_t));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -695,7 +670,7 @@ IdeController::write(Packet &pkt)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (pkt.size == sizeof(uint8_t)) {
|
if (pkt.size == sizeof(uint8_t)) {
|
||||||
disks[disk]->write(offset, reg_type, pkt.data);
|
disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>());
|
||||||
} else
|
} else
|
||||||
panic("IDE write of command reg of invalid size: %#x\n", pkt.size);
|
panic("IDE write of command reg of invalid size: %#x\n", pkt.size);
|
||||||
}
|
}
|
||||||
|
@ -706,13 +681,13 @@ IdeController::write(Packet &pkt)
|
||||||
|
|
||||||
if (pkt.size == 1)
|
if (pkt.size == 1)
|
||||||
DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
|
DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
|
||||||
offset, pkt.size, (uint32_t)data8);
|
offset, pkt.size, (uint32_t)pkt.get<uint8_t>());
|
||||||
else if (pkt.size == 2)
|
else if (pkt.size == 2)
|
||||||
DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
|
DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
|
||||||
offset, pkt.size, *(uint16_t*)pkt.data);
|
offset, pkt.size, pkt.get<uint16_t>());
|
||||||
else
|
else
|
||||||
DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
|
DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
|
||||||
offset, pkt.size, data32);
|
offset, pkt.size, pkt.get<uint32_t>());
|
||||||
|
|
||||||
|
|
||||||
pkt.result = Success;
|
pkt.result = Success;
|
||||||
|
@ -785,6 +760,7 @@ IdeController::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
UNSERIALIZE_SCALAR(bm_enabled);
|
UNSERIALIZE_SCALAR(bm_enabled);
|
||||||
UNSERIALIZE_ARRAY(cmd_in_progress,
|
UNSERIALIZE_ARRAY(cmd_in_progress,
|
||||||
sizeof(cmd_in_progress) / sizeof(cmd_in_progress[0]));
|
sizeof(cmd_in_progress) / sizeof(cmd_in_progress[0]));
|
||||||
|
pioPort->sendStatusChange(Port::RangeChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
#include "dev/ide_ctrl.hh"
|
#include "dev/ide_ctrl.hh"
|
||||||
#include "dev/tsunami.hh"
|
#include "dev/tsunami.hh"
|
||||||
#include "dev/tsunami_pchip.hh"
|
#include "dev/tsunami_pchip.hh"
|
||||||
#include "mem/packet.hh"
|
|
||||||
#include "sim/builder.hh"
|
#include "sim/builder.hh"
|
||||||
#include "sim/sim_object.hh"
|
#include "sim/sim_object.hh"
|
||||||
#include "sim/root.hh"
|
#include "sim/root.hh"
|
||||||
|
@ -236,6 +235,8 @@ IdeDisk::read(const Addr &offset, IdeRegType reg_type, uint8_t *data)
|
||||||
default:
|
default:
|
||||||
panic("Unknown register block!\n");
|
panic("Unknown register block!\n");
|
||||||
}
|
}
|
||||||
|
DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset,
|
||||||
|
(uint32_t)*data);
|
||||||
|
|
||||||
if (action != ACT_NONE)
|
if (action != ACT_NONE)
|
||||||
updateState(action);
|
updateState(action);
|
||||||
|
@ -297,6 +298,8 @@ IdeDisk::write(const Addr &offset, IdeRegType reg_type, const uint8_t *data)
|
||||||
panic("Unknown register block!\n");
|
panic("Unknown register block!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINTF(IdeDisk, "Write to disk at offset: %#x data %#x\n", offset,
|
||||||
|
(uint32_t)*data);
|
||||||
if (action != ACT_NONE)
|
if (action != ACT_NONE)
|
||||||
updateState(action);
|
updateState(action);
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,7 +172,8 @@ DmaPort::dmaAction(Command cmd, Addr addr, int size, Event *event,
|
||||||
pkt->req->setPaddr(pkt->addr);
|
pkt->req->setPaddr(pkt->addr);
|
||||||
pkt->req->setSize(pkt->size);
|
pkt->req->setSize(pkt->size);
|
||||||
// Increment the data pointer on a write
|
// Increment the data pointer on a write
|
||||||
pkt->data = data ? data + prevSize : NULL ;
|
if (data)
|
||||||
|
pkt->dataStatic(data + prevSize) ;
|
||||||
prevSize += pkt->size;
|
prevSize += pkt->size;
|
||||||
// Set the last bit of the dma as the final packet for this dma
|
// Set the last bit of the dma as the final packet for this dma
|
||||||
// and set it's completion event.
|
// and set it's completion event.
|
||||||
|
@ -183,13 +184,16 @@ DmaPort::dmaAction(Command cmd, Addr addr, int size, Event *event,
|
||||||
}
|
}
|
||||||
assert(pendingCount >= 0);
|
assert(pendingCount >= 0);
|
||||||
pendingCount++;
|
pendingCount++;
|
||||||
sendDma(*pkt);
|
sendDma(pkt);
|
||||||
}
|
}
|
||||||
|
// since this isn't getting used and we want a check to make sure that all
|
||||||
|
// packets had data in them at some point.
|
||||||
|
basePkt.dataStatic((uint8_t*)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DmaPort::sendDma(Packet &pkt)
|
DmaPort::sendDma(Packet *pkt)
|
||||||
{
|
{
|
||||||
// some kind of selction between access methods
|
// some kind of selction between access methods
|
||||||
// more work is going to have to be done to make
|
// more work is going to have to be done to make
|
||||||
|
@ -200,13 +204,16 @@ DmaPort::sendDma(Packet &pkt)
|
||||||
if (sendTiming(pkt) == Failure)
|
if (sendTiming(pkt) == Failure)
|
||||||
transmitList.push_back(&packet);
|
transmitList.push_back(&packet);
|
||||||
} else if (state == Atomic) {*/
|
} else if (state == Atomic) {*/
|
||||||
sendAtomic(pkt);
|
sendAtomic(*pkt);
|
||||||
if (pkt.senderState) {
|
if (pkt->senderState) {
|
||||||
DmaReqState *state = (DmaReqState*)pkt.senderState;
|
DmaReqState *state = (DmaReqState*)pkt->senderState;
|
||||||
state->completionEvent->schedule(curTick + (pkt.time - pkt.req->getTime()) +1);
|
state->completionEvent->schedule(curTick + (pkt->time - pkt->req->getTime()) +1);
|
||||||
}
|
}
|
||||||
pendingCount--;
|
pendingCount--;
|
||||||
assert(pendingCount >= 0);
|
assert(pendingCount >= 0);
|
||||||
|
delete pkt->req;
|
||||||
|
delete pkt;
|
||||||
|
|
||||||
/* } else if (state == Functional) {
|
/* } else if (state == Functional) {
|
||||||
sendFunctional(pkt);
|
sendFunctional(pkt);
|
||||||
// Is this correct???
|
// Is this correct???
|
||||||
|
|
|
@ -58,47 +58,17 @@ IsaFake::read(Packet &pkt)
|
||||||
|
|
||||||
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size);
|
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size);
|
||||||
|
|
||||||
uint8_t *data8;
|
|
||||||
uint16_t *data16;
|
|
||||||
uint32_t *data32;
|
|
||||||
uint64_t *data64;
|
|
||||||
|
|
||||||
switch (pkt.size) {
|
switch (pkt.size) {
|
||||||
case sizeof(uint64_t):
|
pkt.set(0xFFFFFFFFFFFFFFFFULL);
|
||||||
if (!pkt.data) {
|
|
||||||
data64 = new uint64_t;
|
|
||||||
pkt.data = (uint8_t*)data64;
|
|
||||||
} else {
|
|
||||||
data64 = (uint64_t*)pkt.data;
|
|
||||||
}
|
|
||||||
*data64 = 0xFFFFFFFFFFFFFFFFULL;
|
|
||||||
break;
|
break;
|
||||||
case sizeof(uint32_t):
|
case sizeof(uint32_t):
|
||||||
if (!pkt.data) {
|
pkt.set((uint32_t)0xFFFFFFFF);
|
||||||
data32 = new uint32_t;
|
|
||||||
pkt.data = (uint8_t*)data32;
|
|
||||||
} else {
|
|
||||||
data32 = (uint32_t*)pkt.data;
|
|
||||||
}
|
|
||||||
*data32 = 0xFFFFFFFF;
|
|
||||||
break;
|
break;
|
||||||
case sizeof(uint16_t):
|
case sizeof(uint16_t):
|
||||||
if (!pkt.data) {
|
pkt.set((uint16_t)0xFFFF);
|
||||||
data16 = new uint16_t;
|
|
||||||
pkt.data = (uint8_t*)data16;
|
|
||||||
} else {
|
|
||||||
data16 = (uint16_t*)pkt.data;
|
|
||||||
}
|
|
||||||
*data16 = 0xFFFF;
|
|
||||||
break;
|
break;
|
||||||
case sizeof(uint8_t):
|
case sizeof(uint8_t):
|
||||||
if (!pkt.data) {
|
pkt.set((uint8_t)0xFF);
|
||||||
data8 = new uint8_t;
|
|
||||||
pkt.data = data8;
|
|
||||||
} else {
|
|
||||||
data8 = (uint8_t*)pkt.data;
|
|
||||||
}
|
|
||||||
*data8 = 0xFF;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("invalid access size(?) for PCI configspace!\n");
|
panic("invalid access size(?) for PCI configspace!\n");
|
||||||
|
|
755
dev/ns_gige.cc
755
dev/ns_gige.cc
File diff suppressed because it is too large
Load diff
|
@ -42,7 +42,6 @@
|
||||||
#include "dev/ns_gige_reg.h"
|
#include "dev/ns_gige_reg.h"
|
||||||
#include "dev/pcidev.hh"
|
#include "dev/pcidev.hh"
|
||||||
#include "dev/pktfifo.hh"
|
#include "dev/pktfifo.hh"
|
||||||
#include "mem/bus/bus.hh"
|
|
||||||
#include "sim/eventq.hh"
|
#include "sim/eventq.hh"
|
||||||
|
|
||||||
// Hash filtering constants
|
// Hash filtering constants
|
||||||
|
@ -111,10 +110,7 @@ struct dp_rom {
|
||||||
};
|
};
|
||||||
|
|
||||||
class NSGigEInt;
|
class NSGigEInt;
|
||||||
class PhysicalMemory;
|
class Packet;
|
||||||
class BaseInterface;
|
|
||||||
class HierParams;
|
|
||||||
class Bus;
|
|
||||||
class PciConfigAll;
|
class PciConfigAll;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -165,10 +161,6 @@ class NSGigE : public PciDev
|
||||||
eepromRead
|
eepromRead
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
|
||||||
Addr addr;
|
|
||||||
static const Addr size = sizeof(dp_regs);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** device register file */
|
/** device register file */
|
||||||
dp_regs regs;
|
dp_regs regs;
|
||||||
|
@ -187,8 +179,8 @@ class NSGigE : public PciDev
|
||||||
PacketFifo rxFifo;
|
PacketFifo rxFifo;
|
||||||
|
|
||||||
/** various helper vars */
|
/** various helper vars */
|
||||||
PacketPtr txPacket;
|
EthPacketPtr txPacket;
|
||||||
PacketPtr rxPacket;
|
EthPacketPtr rxPacket;
|
||||||
uint8_t *txPacketBufPtr;
|
uint8_t *txPacketBufPtr;
|
||||||
uint8_t *rxPacketBufPtr;
|
uint8_t *rxPacketBufPtr;
|
||||||
uint32_t txXferLen;
|
uint32_t txXferLen;
|
||||||
|
@ -258,16 +250,12 @@ class NSGigE : public PciDev
|
||||||
int rxDmaLen;
|
int rxDmaLen;
|
||||||
bool doRxDmaRead();
|
bool doRxDmaRead();
|
||||||
bool doRxDmaWrite();
|
bool doRxDmaWrite();
|
||||||
void rxDmaReadCopy();
|
|
||||||
void rxDmaWriteCopy();
|
|
||||||
|
|
||||||
void *txDmaData;
|
void *txDmaData;
|
||||||
Addr txDmaAddr;
|
Addr txDmaAddr;
|
||||||
int txDmaLen;
|
int txDmaLen;
|
||||||
bool doTxDmaRead();
|
bool doTxDmaRead();
|
||||||
bool doTxDmaWrite();
|
bool doTxDmaWrite();
|
||||||
void txDmaReadCopy();
|
|
||||||
void txDmaWriteCopy();
|
|
||||||
|
|
||||||
void rxDmaReadDone();
|
void rxDmaReadDone();
|
||||||
friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
|
friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
|
||||||
|
@ -331,7 +319,7 @@ class NSGigE : public PciDev
|
||||||
* receive address filter
|
* receive address filter
|
||||||
*/
|
*/
|
||||||
bool rxFilterEnable;
|
bool rxFilterEnable;
|
||||||
bool rxFilter(const PacketPtr &packet);
|
bool rxFilter(const EthPacketPtr &packet);
|
||||||
bool acceptBroadcast;
|
bool acceptBroadcast;
|
||||||
bool acceptMulticast;
|
bool acceptMulticast;
|
||||||
bool acceptUnicast;
|
bool acceptUnicast;
|
||||||
|
@ -339,8 +327,6 @@ class NSGigE : public PciDev
|
||||||
bool acceptArp;
|
bool acceptArp;
|
||||||
bool multicastHashEnable;
|
bool multicastHashEnable;
|
||||||
|
|
||||||
PhysicalMemory *physmem;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interrupt management
|
* Interrupt management
|
||||||
*/
|
*/
|
||||||
|
@ -363,16 +349,10 @@ class NSGigE : public PciDev
|
||||||
public:
|
public:
|
||||||
struct Params : public PciDev::Params
|
struct Params : public PciDev::Params
|
||||||
{
|
{
|
||||||
PhysicalMemory *pmem;
|
|
||||||
HierParams *hier;
|
|
||||||
Bus *pio_bus;
|
|
||||||
Bus *header_bus;
|
|
||||||
Bus *payload_bus;
|
|
||||||
Tick clock;
|
Tick clock;
|
||||||
Tick intr_delay;
|
Tick intr_delay;
|
||||||
Tick tx_delay;
|
Tick tx_delay;
|
||||||
Tick rx_delay;
|
Tick rx_delay;
|
||||||
Tick pio_latency;
|
|
||||||
bool dma_desc_free;
|
bool dma_desc_free;
|
||||||
bool dma_data_free;
|
bool dma_data_free;
|
||||||
Tick dma_read_delay;
|
Tick dma_read_delay;
|
||||||
|
@ -393,16 +373,15 @@ class NSGigE : public PciDev
|
||||||
~NSGigE();
|
~NSGigE();
|
||||||
const Params *params() const { return (const Params *)_params; }
|
const Params *params() const { return (const Params *)_params; }
|
||||||
|
|
||||||
virtual void writeConfig(int offset, int size, const uint8_t *data);
|
virtual void writeConfig(int offset, const uint16_t data);
|
||||||
virtual void readConfig(int offset, int size, uint8_t *data);
|
|
||||||
|
|
||||||
virtual Fault read(MemReqPtr &req, uint8_t *data);
|
virtual Tick read(Packet &pkt);
|
||||||
virtual Fault write(MemReqPtr &req, const uint8_t *data);
|
virtual Tick write(Packet &pkt);
|
||||||
|
|
||||||
bool cpuIntrPending() const;
|
bool cpuIntrPending() const;
|
||||||
void cpuIntrAck() { cpuIntrClear(); }
|
void cpuIntrAck() { cpuIntrClear(); }
|
||||||
|
|
||||||
bool recvPacket(PacketPtr packet);
|
bool recvPacket(EthPacketPtr packet);
|
||||||
void transferDone();
|
void transferDone();
|
||||||
|
|
||||||
void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
|
void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
|
||||||
|
@ -463,9 +442,6 @@ class NSGigE : public PciDev
|
||||||
Stats::Formula coalescedTotal;
|
Stats::Formula coalescedTotal;
|
||||||
Stats::Scalar<> postedInterrupts;
|
Stats::Scalar<> postedInterrupts;
|
||||||
Stats::Scalar<> droppedPackets;
|
Stats::Scalar<> droppedPackets;
|
||||||
|
|
||||||
public:
|
|
||||||
Tick cacheAccess(MemReqPtr &req);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -480,7 +456,7 @@ class NSGigEInt : public EtherInt
|
||||||
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) { dev->setInterface(this); }
|
||||||
|
|
||||||
virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); }
|
virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
|
||||||
virtual void sendDone() { dev->transferDone(); }
|
virtual void sendDone() { dev->transferDone(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -100,62 +100,29 @@ PciConfigAll::read(Packet &pkt)
|
||||||
int reg = daddr & 0xFF;
|
int reg = daddr & 0xFF;
|
||||||
|
|
||||||
pkt.time = curTick + pioDelay;
|
pkt.time = curTick + pioDelay;
|
||||||
|
pkt.allocate();
|
||||||
|
|
||||||
DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt.addr, daddr,
|
DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt.addr, daddr,
|
||||||
pkt.size);
|
pkt.size);
|
||||||
|
|
||||||
uint8_t *data8;
|
|
||||||
uint16_t *data16;
|
|
||||||
uint32_t *data32;
|
|
||||||
|
|
||||||
switch (pkt.size) {
|
switch (pkt.size) {
|
||||||
/* case sizeof(uint64_t):
|
|
||||||
if (!pkt.data) {
|
|
||||||
data64 = new uint64_t;
|
|
||||||
pkt.data = (uint8_t*)data64;
|
|
||||||
} else {
|
|
||||||
data64 = (uint64_t*)pkt.data;
|
|
||||||
}
|
|
||||||
if (devices[device][func] == NULL)
|
|
||||||
*data64 = 0xFFFFFFFFFFFFFFFFULL;
|
|
||||||
else
|
|
||||||
devices[device][func]->readConfig(reg, req.size, data64);
|
|
||||||
break;*/
|
|
||||||
case sizeof(uint32_t):
|
case sizeof(uint32_t):
|
||||||
if (!pkt.data) {
|
|
||||||
data32 = new uint32_t;
|
|
||||||
pkt.data = (uint8_t*)data32;
|
|
||||||
} else {
|
|
||||||
data32 = (uint32_t*)pkt.data;
|
|
||||||
}
|
|
||||||
if (devices[device][func] == NULL)
|
if (devices[device][func] == NULL)
|
||||||
*data32 = 0xFFFFFFFF;
|
pkt.set<uint32_t>(0xFFFFFFFF);
|
||||||
else
|
else
|
||||||
devices[device][func]->readConfig(reg, data32);
|
devices[device][func]->readConfig(reg, pkt.getPtr<uint32_t>());
|
||||||
break;
|
break;
|
||||||
case sizeof(uint16_t):
|
case sizeof(uint16_t):
|
||||||
if (!pkt.data) {
|
|
||||||
data16 = new uint16_t;
|
|
||||||
pkt.data = (uint8_t*)data16;
|
|
||||||
} else {
|
|
||||||
data16 = (uint16_t*)pkt.data;
|
|
||||||
}
|
|
||||||
if (devices[device][func] == NULL)
|
if (devices[device][func] == NULL)
|
||||||
*data16 = 0xFFFF;
|
pkt.set<uint16_t>(0xFFFF);
|
||||||
else
|
else
|
||||||
devices[device][func]->readConfig(reg, data16);
|
devices[device][func]->readConfig(reg, pkt.getPtr<uint16_t>());
|
||||||
break;
|
break;
|
||||||
case sizeof(uint8_t):
|
case sizeof(uint8_t):
|
||||||
if (!pkt.data) {
|
|
||||||
data8 = new uint8_t;
|
|
||||||
pkt.data = data8;
|
|
||||||
} else {
|
|
||||||
data8 = (uint8_t*)pkt.data;
|
|
||||||
}
|
|
||||||
if (devices[device][func] == NULL)
|
if (devices[device][func] == NULL)
|
||||||
*data8 = 0xFF;
|
pkt.set<uint8_t>(0xFF);
|
||||||
else
|
else
|
||||||
devices[device][func]->readConfig(reg, data8);
|
devices[device][func]->readConfig(reg, pkt.getPtr<uint8_t>());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("invalid access size(?) for PCI configspace!\n");
|
panic("invalid access size(?) for PCI configspace!\n");
|
||||||
|
@ -183,17 +150,17 @@ PciConfigAll::write(Packet &pkt)
|
||||||
panic("Attempting to write to config space on non-existant device\n");
|
panic("Attempting to write to config space on non-existant device\n");
|
||||||
|
|
||||||
DPRINTF(PciConfigAll, "write - va=%#x size=%d data=%#x\n",
|
DPRINTF(PciConfigAll, "write - va=%#x size=%d data=%#x\n",
|
||||||
pkt.addr, pkt.size, *(uint32_t*)pkt.data);
|
pkt.addr, pkt.size, pkt.get<uint32_t>());
|
||||||
|
|
||||||
switch (pkt.size) {
|
switch (pkt.size) {
|
||||||
case sizeof(uint8_t):
|
case sizeof(uint8_t):
|
||||||
devices[device][func]->writeConfig(reg, *pkt.data);
|
devices[device][func]->writeConfig(reg, pkt.get<uint8_t>());
|
||||||
break;
|
break;
|
||||||
case sizeof(uint16_t):
|
case sizeof(uint16_t):
|
||||||
devices[device][func]->writeConfig(reg, *(uint16_t*)pkt.data);
|
devices[device][func]->writeConfig(reg, pkt.get<uint16_t>());
|
||||||
break;
|
break;
|
||||||
case sizeof(uint32_t):
|
case sizeof(uint32_t):
|
||||||
devices[device][func]->writeConfig(reg, *(uint32_t*)pkt.data);
|
devices[device][func]->writeConfig(reg, pkt.get<uint32_t>());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("invalid pci config write size\n");
|
panic("invalid pci config write size\n");
|
||||||
|
|
|
@ -38,8 +38,8 @@ PacketFifo::copyout(void *dest, int offset, int len)
|
||||||
if (offset + len >= size())
|
if (offset + len >= size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
list<PacketPtr>::iterator p = fifo.begin();
|
list<EthPacketPtr>::iterator p = fifo.begin();
|
||||||
list<PacketPtr>::iterator end = fifo.end();
|
list<EthPacketPtr>::iterator end = fifo.end();
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
while (offset >= (*p)->length) {
|
while (offset >= (*p)->length) {
|
||||||
offset -= (*p)->length;
|
offset -= (*p)->length;
|
||||||
|
@ -70,8 +70,8 @@ PacketFifo::serialize(const string &base, ostream &os)
|
||||||
paramOut(os, base + ".packets", fifo.size());
|
paramOut(os, base + ".packets", fifo.size());
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
list<PacketPtr>::iterator p = fifo.begin();
|
list<EthPacketPtr>::iterator p = fifo.begin();
|
||||||
list<PacketPtr>::iterator end = fifo.end();
|
list<EthPacketPtr>::iterator end = fifo.end();
|
||||||
while (p != end) {
|
while (p != end) {
|
||||||
(*p)->serialize(csprintf("%s.packet%d", base, i), os);
|
(*p)->serialize(csprintf("%s.packet%d", base, i), os);
|
||||||
++p;
|
++p;
|
||||||
|
@ -92,7 +92,7 @@ PacketFifo::unserialize(const string &base, Checkpoint *cp,
|
||||||
fifo.clear();
|
fifo.clear();
|
||||||
|
|
||||||
for (int i = 0; i < fifosize; ++i) {
|
for (int i = 0; i < fifosize; ++i) {
|
||||||
PacketPtr p = new PacketData(16384);
|
EthPacketPtr p = new EthPacketData(16384);
|
||||||
p->unserialize(csprintf("%s.packet%d", base, i), cp, section);
|
p->unserialize(csprintf("%s.packet%d", base, i), cp, section);
|
||||||
fifo.push_back(p);
|
fifo.push_back(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,11 +40,11 @@ class Checkpoint;
|
||||||
class PacketFifo
|
class PacketFifo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::list<PacketPtr> fifo_list;
|
typedef std::list<EthPacketPtr> fifo_list;
|
||||||
typedef fifo_list::iterator iterator;
|
typedef fifo_list::iterator iterator;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::list<PacketPtr> fifo;
|
std::list<EthPacketPtr> fifo;
|
||||||
int _maxsize;
|
int _maxsize;
|
||||||
int _size;
|
int _size;
|
||||||
int _reserved;
|
int _reserved;
|
||||||
|
@ -71,9 +71,9 @@ class PacketFifo
|
||||||
iterator begin() { return fifo.begin(); }
|
iterator begin() { return fifo.begin(); }
|
||||||
iterator end() { return fifo.end(); }
|
iterator end() { return fifo.end(); }
|
||||||
|
|
||||||
PacketPtr front() { return fifo.front(); }
|
EthPacketPtr front() { return fifo.front(); }
|
||||||
|
|
||||||
bool push(PacketPtr ptr)
|
bool push(EthPacketPtr ptr)
|
||||||
{
|
{
|
||||||
assert(ptr->length);
|
assert(ptr->length);
|
||||||
assert(_reserved <= ptr->length);
|
assert(_reserved <= ptr->length);
|
||||||
|
@ -92,7 +92,7 @@ class PacketFifo
|
||||||
if (empty())
|
if (empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PacketPtr &packet = fifo.front();
|
EthPacketPtr &packet = fifo.front();
|
||||||
_size -= packet->length;
|
_size -= packet->length;
|
||||||
_size -= packet->slack;
|
_size -= packet->slack;
|
||||||
packet->slack = 0;
|
packet->slack = 0;
|
||||||
|
@ -111,7 +111,7 @@ class PacketFifo
|
||||||
|
|
||||||
void remove(iterator i)
|
void remove(iterator i)
|
||||||
{
|
{
|
||||||
PacketPtr &packet = *i;
|
EthPacketPtr &packet = *i;
|
||||||
if (i != fifo.begin()) {
|
if (i != fifo.begin()) {
|
||||||
iterator prev = i;
|
iterator prev = i;
|
||||||
--prev;
|
--prev;
|
||||||
|
|
334
dev/sinic.cc
334
dev/sinic.cc
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <limits>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "base/inet.hh"
|
#include "base/inet.hh"
|
||||||
|
@ -36,12 +37,7 @@
|
||||||
#include "dev/etherlink.hh"
|
#include "dev/etherlink.hh"
|
||||||
#include "dev/sinic.hh"
|
#include "dev/sinic.hh"
|
||||||
#include "dev/pciconfigall.hh"
|
#include "dev/pciconfigall.hh"
|
||||||
#include "mem/bus/bus.hh"
|
#include "mem/packet.hh"
|
||||||
#include "mem/bus/dma_interface.hh"
|
|
||||||
#include "mem/bus/pio_interface.hh"
|
|
||||||
#include "mem/bus/pio_interface_impl.hh"
|
|
||||||
#include "mem/functional/memory_control.hh"
|
|
||||||
#include "mem/functional/physical.hh"
|
|
||||||
#include "sim/builder.hh"
|
#include "sim/builder.hh"
|
||||||
#include "sim/debug.hh"
|
#include "sim/debug.hh"
|
||||||
#include "sim/eventq.hh"
|
#include "sim/eventq.hh"
|
||||||
|
@ -85,8 +81,7 @@ Base::Base(Params *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::Device(Params *p)
|
Device::Device(Params *p)
|
||||||
: Base(p), plat(p->plat), physmem(p->physmem),
|
: Base(p), rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size),
|
||||||
rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size),
|
|
||||||
rxKickTick(0), txKickTick(0),
|
rxKickTick(0), txKickTick(0),
|
||||||
txEvent(this), rxDmaEvent(this), txDmaEvent(this),
|
txEvent(this), rxDmaEvent(this), txDmaEvent(this),
|
||||||
dmaReadDelay(p->dma_read_delay), dmaReadFactor(p->dma_read_factor),
|
dmaReadDelay(p->dma_read_delay), dmaReadFactor(p->dma_read_factor),
|
||||||
|
@ -94,25 +89,6 @@ Device::Device(Params *p)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
if (p->pio_bus) {
|
|
||||||
pioInterface = newPioInterface(p->name + ".pio", p->hier, p->pio_bus,
|
|
||||||
this, &Device::cacheAccess);
|
|
||||||
pioLatency = p->pio_latency * p->pio_bus->clockRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p->header_bus) {
|
|
||||||
if (p->payload_bus)
|
|
||||||
dmaInterface = new DMAInterface<Bus>(p->name + ".dma",
|
|
||||||
p->header_bus,
|
|
||||||
p->payload_bus, 1,
|
|
||||||
p->dma_no_allocate);
|
|
||||||
else
|
|
||||||
dmaInterface = new DMAInterface<Bus>(p->name + ".dma",
|
|
||||||
p->header_bus,
|
|
||||||
p->header_bus, 1,
|
|
||||||
p->dma_no_allocate);
|
|
||||||
} else if (p->payload_bus)
|
|
||||||
panic("must define a header bus if defining a payload bus");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::~Device()
|
Device::~Device()
|
||||||
|
@ -288,29 +264,6 @@ Device::regStats()
|
||||||
rxPacketRate = rxPackets / simSeconds;
|
rxPacketRate = rxPackets / simSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This is to write to the PCI general configuration registers
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
Device::writeConfig(int offset, int size, const uint8_t *data)
|
|
||||||
{
|
|
||||||
switch (offset) {
|
|
||||||
case PCI0_BASE_ADDR0:
|
|
||||||
// Need to catch writes to BARs to update the PIO interface
|
|
||||||
PciDev::writeConfig(offset, size, data);
|
|
||||||
if (BARAddrs[0] != 0) {
|
|
||||||
if (pioInterface)
|
|
||||||
pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0]));
|
|
||||||
|
|
||||||
BARAddrs[0] &= EV5::PAddrUncachedMask;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
PciDev::writeConfig(offset, size, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Device::prepareIO(int cpu, int index)
|
Device::prepareIO(int cpu, int index)
|
||||||
{
|
{
|
||||||
|
@ -357,73 +310,64 @@ Device::prepareWrite(int cpu, int index)
|
||||||
/**
|
/**
|
||||||
* I/O read of device register
|
* I/O read of device register
|
||||||
*/
|
*/
|
||||||
Fault
|
Tick
|
||||||
Device::read(MemReqPtr &req, uint8_t *data)
|
Device::read(Packet &pkt)
|
||||||
{
|
{
|
||||||
assert(config.command & PCI_CMD_MSE);
|
assert(config.command & PCI_CMD_MSE);
|
||||||
Fault fault = readBar(req, data);
|
assert(pkt.addr >= BARAddrs[0] && pkt.size < BARSize[0]);
|
||||||
|
|
||||||
if (fault->isMachineCheckFault()) {
|
int cpu = pkt.req->getCpuNum();
|
||||||
panic("address does not map to a BAR pa=%#x va=%#x size=%d",
|
Addr daddr = pkt.addr - BARAddrs[0];
|
||||||
req->paddr, req->vaddr, req->size);
|
|
||||||
|
|
||||||
return genMachineCheckFault();
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
|
||||||
}
|
|
||||||
|
|
||||||
Fault
|
|
||||||
Device::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data)
|
|
||||||
{
|
|
||||||
int cpu = (req->xc->readMiscReg(TheISA::IPR_PALtemp16) >> 8) & 0xff;
|
|
||||||
Addr index = daddr >> Regs::VirtualShift;
|
Addr index = daddr >> Regs::VirtualShift;
|
||||||
Addr raddr = daddr & Regs::VirtualMask;
|
Addr raddr = daddr & Regs::VirtualMask;
|
||||||
|
|
||||||
|
pkt.time = curTick + pioDelay;
|
||||||
|
pkt.allocate();
|
||||||
|
|
||||||
if (!regValid(raddr))
|
if (!regValid(raddr))
|
||||||
panic("invalid register: cpu=%d, da=%#x pa=%#x va=%#x size=%d",
|
panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d",
|
||||||
cpu, daddr, req->paddr, req->vaddr, req->size);
|
cpu, daddr, pkt.addr, pkt.size);
|
||||||
|
|
||||||
const Regs::Info &info = regInfo(raddr);
|
const Regs::Info &info = regInfo(raddr);
|
||||||
if (!info.read)
|
if (!info.read)
|
||||||
panic("reading %s (write only): cpu=%d da=%#x pa=%#x va=%#x size=%d",
|
panic("reading %s (write only): cpu=%d da=%#x pa=%#x size=%d",
|
||||||
info.name, cpu, daddr, req->paddr, req->vaddr, req->size);
|
info.name, cpu, daddr, pkt.addr, pkt.size);
|
||||||
|
|
||||||
if (req->size != info.size)
|
if (pkt.size != info.size)
|
||||||
panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x va=%#x size=%d",
|
panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x size=%d",
|
||||||
info.name, cpu, daddr, req->paddr, req->vaddr, req->size);
|
info.name, cpu, daddr, pkt.addr, pkt.size);
|
||||||
|
|
||||||
prepareRead(cpu, index);
|
prepareRead(cpu, index);
|
||||||
|
|
||||||
uint64_t value = 0;
|
uint64_t value = 0;
|
||||||
if (req->size == 4) {
|
if (pkt.size == 4) {
|
||||||
uint32_t ® = *(uint32_t *)data;
|
uint32_t reg = regData32(raddr);
|
||||||
reg = regData32(raddr);
|
pkt.set(reg);
|
||||||
value = reg;
|
value = reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->size == 8) {
|
if (pkt.size == 8) {
|
||||||
uint64_t ® = *(uint64_t *)data;
|
uint64_t reg = regData64(raddr);
|
||||||
reg = regData64(raddr);
|
pkt.set(reg);
|
||||||
value = reg;
|
value = reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(EthernetPIO,
|
DPRINTF(EthernetPIO,
|
||||||
"read %s cpu=%d da=%#x pa=%#x va=%#x size=%d val=%#x\n",
|
"read %s cpu=%d da=%#x pa=%#x size=%d val=%#x\n",
|
||||||
info.name, cpu, daddr, req->paddr, req->vaddr, req->size, value);
|
info.name, cpu, daddr, pkt.addr, pkt.size, value);
|
||||||
|
|
||||||
// reading the interrupt status register has the side effect of
|
// reading the interrupt status register has the side effect of
|
||||||
// clearing it
|
// clearing it
|
||||||
if (raddr == Regs::IntrStatus)
|
if (raddr == Regs::IntrStatus)
|
||||||
devIntrClear();
|
devIntrClear();
|
||||||
|
|
||||||
return NoFault;
|
return pioDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IPR read of device register
|
* IPR read of device register
|
||||||
*/
|
|
||||||
Fault
|
Fault
|
||||||
Device::iprRead(Addr daddr, int cpu, uint64_t &result)
|
Device::iprRead(Addr daddr, int cpu, uint64_t &result)
|
||||||
{
|
{
|
||||||
if (!regValid(daddr))
|
if (!regValid(daddr))
|
||||||
|
@ -449,72 +393,60 @@ Device::iprRead(Addr daddr, int cpu, uint64_t &result)
|
||||||
|
|
||||||
return NoFault;
|
return NoFault;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* I/O write of device register
|
* I/O write of device register
|
||||||
*/
|
*/
|
||||||
Fault
|
Tick
|
||||||
Device::write(MemReqPtr &req, const uint8_t *data)
|
Device::write(Packet &pkt)
|
||||||
{
|
{
|
||||||
assert(config.command & PCI_CMD_MSE);
|
assert(config.command & PCI_CMD_MSE);
|
||||||
Fault fault = writeBar(req, data);
|
assert(pkt.addr >= BARAddrs[0] && pkt.size < BARSize[0]);
|
||||||
|
|
||||||
if (fault->isMachineCheckFault()) {
|
int cpu = pkt.req->getCpuNum();
|
||||||
panic("address does not map to a BAR pa=%#x va=%#x size=%d",
|
Addr daddr = pkt.addr - BARAddrs[0];
|
||||||
req->paddr, req->vaddr, req->size);
|
|
||||||
|
|
||||||
return genMachineCheckFault();
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
|
||||||
}
|
|
||||||
|
|
||||||
Fault
|
|
||||||
Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
|
|
||||||
{
|
|
||||||
int cpu = (req->xc->readMiscReg(TheISA::IPR_PALtemp16) >> 8) & 0xff;
|
|
||||||
Addr index = daddr >> Regs::VirtualShift;
|
Addr index = daddr >> Regs::VirtualShift;
|
||||||
Addr raddr = daddr & Regs::VirtualMask;
|
Addr raddr = daddr & Regs::VirtualMask;
|
||||||
|
|
||||||
|
pkt.time = curTick + pioDelay;
|
||||||
|
|
||||||
if (!regValid(raddr))
|
if (!regValid(raddr))
|
||||||
panic("invalid address: cpu=%d da=%#x pa=%#x va=%#x size=%d",
|
panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d",
|
||||||
cpu, daddr, req->paddr, req->vaddr, req->size);
|
cpu, daddr, pkt.addr, pkt.size);
|
||||||
|
|
||||||
const Regs::Info &info = regInfo(raddr);
|
const Regs::Info &info = regInfo(raddr);
|
||||||
if (!info.write)
|
if (!info.write)
|
||||||
panic("writing %s (read only): cpu=%d da=%#x",
|
panic("write %s (read only): cpu=%d da=%#x pa=%#x size=%d",
|
||||||
info.name, cpu, daddr);
|
info.name, cpu, daddr, pkt.addr, pkt.size);
|
||||||
|
|
||||||
if (req->size != info.size)
|
if (pkt.size != info.size)
|
||||||
panic("invalid size for %s: cpu=%d da=%#x pa=%#x va=%#x size=%d",
|
panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x size=%d",
|
||||||
info.name, cpu, daddr, req->paddr, req->vaddr, req->size);
|
info.name, cpu, daddr, pkt.addr, pkt.size);
|
||||||
|
|
||||||
uint32_t reg32 = *(uint32_t *)data;
|
|
||||||
uint64_t reg64 = *(uint64_t *)data;
|
|
||||||
VirtualReg &vnic = virtualRegs[index];
|
VirtualReg &vnic = virtualRegs[index];
|
||||||
|
|
||||||
DPRINTF(EthernetPIO,
|
DPRINTF(EthernetPIO,
|
||||||
"write %s: cpu=%d val=%#x da=%#x pa=%#x va=%#x size=%d\n",
|
"write %s: cpu=%d val=%#x da=%#x pa=%#x size=%d\n",
|
||||||
info.name, cpu, info.size == 4 ? reg32 : reg64,
|
info.name, cpu, info.size == 4 ? pkt.get<uint32_t>() :
|
||||||
daddr, req->paddr, req->vaddr, req->size);
|
pkt.get<uint64_t>(), daddr, pkt.addr, pkt.size);
|
||||||
|
|
||||||
prepareWrite(cpu, index);
|
prepareWrite(cpu, index);
|
||||||
|
|
||||||
switch (raddr) {
|
switch (raddr) {
|
||||||
case Regs::Config:
|
case Regs::Config:
|
||||||
changeConfig(reg32);
|
changeConfig(pkt.get<uint32_t>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Regs::Command:
|
case Regs::Command:
|
||||||
command(reg32);
|
command(pkt.get<uint32_t>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Regs::IntrStatus:
|
case Regs::IntrStatus:
|
||||||
devIntrClear(regs.IntrStatus & reg32);
|
devIntrClear(regs.IntrStatus & pkt.get<uint32_t>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Regs::IntrMask:
|
case Regs::IntrMask:
|
||||||
devIntrChangeMask(reg32);
|
devIntrChangeMask(pkt.get<uint32_t>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Regs::RxData:
|
case Regs::RxData:
|
||||||
|
@ -523,7 +455,7 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
|
||||||
RxStateStrings[rxState]);
|
RxStateStrings[rxState]);
|
||||||
|
|
||||||
vnic.RxDone = Regs::RxDone_Busy;
|
vnic.RxDone = Regs::RxDone_Busy;
|
||||||
vnic.RxData = reg64;
|
vnic.RxData = pkt.get<uint64_t>();
|
||||||
rxList.push_back(index);
|
rxList.push_back(index);
|
||||||
if (rxEnable && rxState == rxIdle) {
|
if (rxEnable && rxState == rxIdle) {
|
||||||
rxState = rxFifoBlock;
|
rxState = rxFifoBlock;
|
||||||
|
@ -537,7 +469,7 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
|
||||||
TxStateStrings[txState]);
|
TxStateStrings[txState]);
|
||||||
|
|
||||||
vnic.TxDone = Regs::TxDone_Busy;
|
vnic.TxDone = Regs::TxDone_Busy;
|
||||||
vnic.TxData = reg64;
|
vnic.TxData = pkt.get<uint64_t>();
|
||||||
if (txList.empty() || txList.front() != index)
|
if (txList.empty() || txList.front() != index)
|
||||||
txList.push_back(index);
|
txList.push_back(index);
|
||||||
if (txEnable && txState == txIdle && txList.front() == index) {
|
if (txEnable && txState == txIdle && txList.front() == index) {
|
||||||
|
@ -547,7 +479,7 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NoFault;
|
return pioDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -793,20 +725,13 @@ Device::reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Device::rxDmaCopy()
|
Device::rxDmaDone()
|
||||||
{
|
{
|
||||||
assert(rxState == rxCopy);
|
assert(rxState == rxCopy);
|
||||||
rxState = rxCopyDone;
|
rxState = rxCopyDone;
|
||||||
physmem->dma_write(rxDmaAddr, (uint8_t *)rxDmaData, rxDmaLen);
|
|
||||||
DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n",
|
DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n",
|
||||||
rxDmaAddr, rxDmaLen);
|
rxDmaAddr, rxDmaLen);
|
||||||
DDUMP(EthernetData, rxDmaData, rxDmaLen);
|
DDUMP(EthernetData, rxDmaData, rxDmaLen);
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Device::rxDmaDone()
|
|
||||||
{
|
|
||||||
rxDmaCopy();
|
|
||||||
|
|
||||||
// If the transmit state machine has a pending DMA, let it go first
|
// If the transmit state machine has a pending DMA, let it go first
|
||||||
if (txState == txBeginCopy)
|
if (txState == txBeginCopy)
|
||||||
|
@ -892,29 +817,17 @@ Device::rxKick()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case rxBeginCopy:
|
case rxBeginCopy:
|
||||||
if (dmaInterface && dmaInterface->busy())
|
if (dmaPending())
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
rxDmaAddr = plat->pciToDma(Regs::get_RxData_Addr(vnic->RxData));
|
rxDmaAddr = params()->platform->pciToDma(
|
||||||
rxDmaLen = min<int>(Regs::get_RxData_Len(vnic->RxData),
|
Regs::get_RxData_Addr(vnic->RxData));
|
||||||
|
rxDmaLen = std::min<int>(Regs::get_RxData_Len(vnic->RxData),
|
||||||
vnic->rxPacketBytes);
|
vnic->rxPacketBytes);
|
||||||
rxDmaData = (*vnic->rxPacket)->data + vnic->rxPacketOffset;
|
rxDmaData = (*vnic->rxPacket)->data + vnic->rxPacketOffset;
|
||||||
rxState = rxCopy;
|
rxState = rxCopy;
|
||||||
|
|
||||||
if (dmaInterface) {
|
dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaEvent, rxDmaData);
|
||||||
dmaInterface->doDMA(WriteInvalidate, rxDmaAddr, rxDmaLen,
|
|
||||||
curTick, &rxDmaEvent, true);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dmaWriteDelay != 0 || dmaWriteFactor != 0) {
|
|
||||||
Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor;
|
|
||||||
Tick start = curTick + dmaWriteDelay + factor;
|
|
||||||
rxDmaEvent.schedule(start);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
rxDmaCopy();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case rxCopy:
|
case rxCopy:
|
||||||
|
@ -968,20 +881,13 @@ Device::rxKick()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Device::txDmaCopy()
|
Device::txDmaDone()
|
||||||
{
|
{
|
||||||
assert(txState == txCopy);
|
assert(txState == txCopy);
|
||||||
txState = txCopyDone;
|
txState = txCopyDone;
|
||||||
physmem->dma_read((uint8_t *)txDmaData, txDmaAddr, txDmaLen);
|
|
||||||
DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n",
|
DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n",
|
||||||
txDmaAddr, txDmaLen);
|
txDmaAddr, txDmaLen);
|
||||||
DDUMP(EthernetData, txDmaData, txDmaLen);
|
DDUMP(EthernetData, txDmaData, txDmaLen);
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Device::txDmaDone()
|
|
||||||
{
|
|
||||||
txDmaCopy();
|
|
||||||
|
|
||||||
// If the receive state machine has a pending DMA, let it go first
|
// If the receive state machine has a pending DMA, let it go first
|
||||||
if (rxState == rxBeginCopy)
|
if (rxState == rxBeginCopy)
|
||||||
|
@ -999,7 +905,7 @@ Device::transmit()
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t interrupts;
|
uint32_t interrupts;
|
||||||
PacketPtr packet = txFifo.front();
|
EthPacketPtr packet = txFifo.front();
|
||||||
if (!interface->sendPacket(packet)) {
|
if (!interface->sendPacket(packet)) {
|
||||||
DPRINTF(Ethernet, "Packet Transmit: failed txFifo available %d\n",
|
DPRINTF(Ethernet, "Packet Transmit: failed txFifo available %d\n",
|
||||||
txFifo.avail());
|
txFifo.avail());
|
||||||
|
@ -1065,7 +971,7 @@ Device::txKick()
|
||||||
assert(Regs::get_TxDone_Busy(vnic->TxData));
|
assert(Regs::get_TxDone_Busy(vnic->TxData));
|
||||||
if (!txPacket) {
|
if (!txPacket) {
|
||||||
// Grab a new packet from the fifo.
|
// Grab a new packet from the fifo.
|
||||||
txPacket = new PacketData(16384);
|
txPacket = new EthPacketData(16384);
|
||||||
txPacketOffset = 0;
|
txPacketOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1079,28 +985,16 @@ Device::txKick()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case txBeginCopy:
|
case txBeginCopy:
|
||||||
if (dmaInterface && dmaInterface->busy())
|
if (dmaPending())
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
txDmaAddr = plat->pciToDma(Regs::get_TxData_Addr(vnic->TxData));
|
txDmaAddr = params()->platform->pciToDma(
|
||||||
|
Regs::get_TxData_Addr(vnic->TxData));
|
||||||
txDmaLen = Regs::get_TxData_Len(vnic->TxData);
|
txDmaLen = Regs::get_TxData_Len(vnic->TxData);
|
||||||
txDmaData = txPacket->data + txPacketOffset;
|
txDmaData = txPacket->data + txPacketOffset;
|
||||||
txState = txCopy;
|
txState = txCopy;
|
||||||
|
|
||||||
if (dmaInterface) {
|
dmaRead(txDmaAddr, txDmaLen, &txDmaEvent, txDmaData);
|
||||||
dmaInterface->doDMA(Read, txDmaAddr, txDmaLen,
|
|
||||||
curTick, &txDmaEvent, true);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dmaReadDelay != 0 || dmaReadFactor != 0) {
|
|
||||||
Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor;
|
|
||||||
Tick start = curTick + dmaReadDelay + factor;
|
|
||||||
txDmaEvent.schedule(start);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
txDmaCopy();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case txCopy:
|
case txCopy:
|
||||||
|
@ -1187,7 +1081,7 @@ Device::transferDone()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Device::rxFilter(const PacketPtr &packet)
|
Device::rxFilter(const EthPacketPtr &packet)
|
||||||
{
|
{
|
||||||
if (!Regs::get_Config_Filter(regs.Config))
|
if (!Regs::get_Config_Filter(regs.Config))
|
||||||
return false;
|
return false;
|
||||||
|
@ -1232,7 +1126,7 @@ Device::rxFilter(const PacketPtr &packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Device::recvPacket(PacketPtr packet)
|
Device::recvPacket(EthPacketPtr packet)
|
||||||
{
|
{
|
||||||
rxBytes += packet->length;
|
rxBytes += packet->length;
|
||||||
rxPackets++;
|
rxPackets++;
|
||||||
|
@ -1273,7 +1167,7 @@ Device::recvPacket(PacketPtr packet)
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
void
|
void
|
||||||
Base::serialize(ostream &os)
|
Base::serialize(std::ostream &os)
|
||||||
{
|
{
|
||||||
// Serialize the PciDev base class
|
// Serialize the PciDev base class
|
||||||
PciDev::serialize(os);
|
PciDev::serialize(os);
|
||||||
|
@ -1317,7 +1211,7 @@ Base::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Device::serialize(ostream &os)
|
Device::serialize(std::ostream &os)
|
||||||
{
|
{
|
||||||
// Serialize the PciDev base class
|
// Serialize the PciDev base class
|
||||||
Base::serialize(os);
|
Base::serialize(os);
|
||||||
|
@ -1352,7 +1246,7 @@ Device::serialize(ostream &os)
|
||||||
for (int i = 0; i < virtualRegsSize; ++i) {
|
for (int i = 0; i < virtualRegsSize; ++i) {
|
||||||
VirtualReg *vnic = &virtualRegs[i];
|
VirtualReg *vnic = &virtualRegs[i];
|
||||||
|
|
||||||
string reg = csprintf("vnic%d", i);
|
std::string reg = csprintf("vnic%d", i);
|
||||||
paramOut(os, reg + ".RxData", vnic->RxData);
|
paramOut(os, reg + ".RxData", vnic->RxData);
|
||||||
paramOut(os, reg + ".RxDone", vnic->RxDone);
|
paramOut(os, reg + ".RxDone", vnic->RxDone);
|
||||||
paramOut(os, reg + ".TxData", vnic->TxData);
|
paramOut(os, reg + ".TxData", vnic->TxData);
|
||||||
|
@ -1481,7 +1375,7 @@ Device::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
UNSERIALIZE_SCALAR(txPacketExists);
|
UNSERIALIZE_SCALAR(txPacketExists);
|
||||||
txPacket = 0;
|
txPacket = 0;
|
||||||
if (txPacketExists) {
|
if (txPacketExists) {
|
||||||
txPacket = new PacketData(16384);
|
txPacket = new EthPacketData(16384);
|
||||||
txPacket->unserialize("txPacket", cp, section);
|
txPacket->unserialize("txPacket", cp, section);
|
||||||
UNSERIALIZE_SCALAR(txPacketOffset);
|
UNSERIALIZE_SCALAR(txPacketOffset);
|
||||||
UNSERIALIZE_SCALAR(txPacketBytes);
|
UNSERIALIZE_SCALAR(txPacketBytes);
|
||||||
|
@ -1499,7 +1393,7 @@ Device::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
virtualRegs.resize(virtualRegsSize);
|
virtualRegs.resize(virtualRegsSize);
|
||||||
for (int i = 0; i < virtualRegsSize; ++i) {
|
for (int i = 0; i < virtualRegsSize; ++i) {
|
||||||
VirtualReg *vnic = &virtualRegs[i];
|
VirtualReg *vnic = &virtualRegs[i];
|
||||||
string reg = csprintf("vnic%d", i);
|
std::string reg = csprintf("vnic%d", i);
|
||||||
|
|
||||||
paramIn(cp, section, reg + ".RxData", vnic->RxData);
|
paramIn(cp, section, reg + ".RxData", vnic->RxData);
|
||||||
paramIn(cp, section, reg + ".RxDone", vnic->RxDone);
|
paramIn(cp, section, reg + ".RxDone", vnic->RxDone);
|
||||||
|
@ -1532,29 +1426,10 @@ Device::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
if (transmitTick)
|
if (transmitTick)
|
||||||
txEvent.schedule(curTick + transmitTick);
|
txEvent.schedule(curTick + transmitTick);
|
||||||
|
|
||||||
/*
|
pioPort->sendStatusChange(Port::RangeChange);
|
||||||
* re-add addrRanges to bus bridges
|
|
||||||
*/
|
|
||||||
if (pioInterface) {
|
|
||||||
pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0]));
|
|
||||||
pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tick
|
|
||||||
Device::cacheAccess(MemReqPtr &req)
|
|
||||||
{
|
|
||||||
Addr daddr;
|
|
||||||
int bar;
|
|
||||||
if (!getBAR(req->paddr, daddr, bar))
|
|
||||||
panic("address does not map to a BAR pa=%#x va=%#x size=%d",
|
|
||||||
req->paddr, req->vaddr, req->size);
|
|
||||||
|
|
||||||
DPRINTF(EthernetPIO, "timing %s to paddr=%#x bar=%d daddr=%#x\n",
|
|
||||||
req->cmd.toString(), req->paddr, bar, daddr);
|
|
||||||
|
|
||||||
return curTick + pioLatency;
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Interface)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Interface)
|
||||||
|
|
||||||
|
@ -1588,29 +1463,22 @@ REGISTER_SIM_OBJECT("SinicInt", Interface)
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
|
||||||
|
|
||||||
Param<Tick> clock;
|
|
||||||
|
|
||||||
Param<Addr> addr;
|
SimObjectParam<System *> system;
|
||||||
SimObjectParam<MemoryController *> mmu;
|
SimObjectParam<Platform *> platform;
|
||||||
SimObjectParam<PhysicalMemory *> physmem;
|
|
||||||
SimObjectParam<PciConfigAll *> configspace;
|
SimObjectParam<PciConfigAll *> configspace;
|
||||||
SimObjectParam<PciConfigData *> configdata;
|
SimObjectParam<PciConfigData *> configdata;
|
||||||
SimObjectParam<Platform *> platform;
|
|
||||||
Param<uint32_t> pci_bus;
|
Param<uint32_t> pci_bus;
|
||||||
Param<uint32_t> pci_dev;
|
Param<uint32_t> pci_dev;
|
||||||
Param<uint32_t> pci_func;
|
Param<uint32_t> pci_func;
|
||||||
|
Param<Tick> pio_latency;
|
||||||
|
Param<Tick> intr_delay;
|
||||||
|
|
||||||
SimObjectParam<HierParams *> hier;
|
Param<Tick> clock;
|
||||||
SimObjectParam<Bus*> pio_bus;
|
|
||||||
SimObjectParam<Bus*> dma_bus;
|
|
||||||
SimObjectParam<Bus*> payload_bus;
|
|
||||||
Param<Tick> dma_read_delay;
|
Param<Tick> dma_read_delay;
|
||||||
Param<Tick> dma_read_factor;
|
Param<Tick> dma_read_factor;
|
||||||
Param<Tick> dma_write_delay;
|
Param<Tick> dma_write_delay;
|
||||||
Param<Tick> dma_write_factor;
|
Param<Tick> dma_write_factor;
|
||||||
Param<bool> dma_no_allocate;
|
|
||||||
Param<Tick> pio_latency;
|
|
||||||
Param<Tick> intr_delay;
|
|
||||||
|
|
||||||
Param<Tick> rx_delay;
|
Param<Tick> rx_delay;
|
||||||
Param<Tick> tx_delay;
|
Param<Tick> tx_delay;
|
||||||
|
@ -1623,7 +1491,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
|
||||||
Param<uint32_t> tx_fifo_threshold;
|
Param<uint32_t> tx_fifo_threshold;
|
||||||
|
|
||||||
Param<bool> rx_filter;
|
Param<bool> rx_filter;
|
||||||
Param<string> hardware_address;
|
Param<std::string> hardware_address;
|
||||||
Param<bool> rx_thread;
|
Param<bool> rx_thread;
|
||||||
Param<bool> tx_thread;
|
Param<bool> tx_thread;
|
||||||
Param<bool> rss;
|
Param<bool> rss;
|
||||||
|
@ -1632,29 +1500,22 @@ END_DECLARE_SIM_OBJECT_PARAMS(Device)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(Device)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(Device)
|
||||||
|
|
||||||
INIT_PARAM(clock, "State machine cycle time"),
|
|
||||||
|
|
||||||
INIT_PARAM(addr, "Device Address"),
|
INIT_PARAM(system, "System pointer"),
|
||||||
INIT_PARAM(mmu, "Memory Controller"),
|
INIT_PARAM(platform, "Platform pointer"),
|
||||||
INIT_PARAM(physmem, "Physical Memory"),
|
|
||||||
INIT_PARAM(configspace, "PCI Configspace"),
|
INIT_PARAM(configspace, "PCI Configspace"),
|
||||||
INIT_PARAM(configdata, "PCI Config data"),
|
INIT_PARAM(configdata, "PCI Config data"),
|
||||||
INIT_PARAM(platform, "Platform"),
|
INIT_PARAM(pci_bus, "PCI bus ID"),
|
||||||
INIT_PARAM(pci_bus, "PCI bus"),
|
|
||||||
INIT_PARAM(pci_dev, "PCI device number"),
|
INIT_PARAM(pci_dev, "PCI device number"),
|
||||||
INIT_PARAM(pci_func, "PCI function code"),
|
INIT_PARAM(pci_func, "PCI function code"),
|
||||||
|
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
|
||||||
|
INIT_PARAM(intr_delay, "Interrupt Delay"),
|
||||||
|
INIT_PARAM(clock, "State machine cycle time"),
|
||||||
|
|
||||||
INIT_PARAM(hier, "Hierarchy global variables"),
|
|
||||||
INIT_PARAM(pio_bus, ""),
|
|
||||||
INIT_PARAM(dma_bus, ""),
|
|
||||||
INIT_PARAM(payload_bus, "The IO Bus to attach to for payload"),
|
|
||||||
INIT_PARAM(dma_read_delay, "fixed delay for dma reads"),
|
INIT_PARAM(dma_read_delay, "fixed delay for dma reads"),
|
||||||
INIT_PARAM(dma_read_factor, "multiplier for dma reads"),
|
INIT_PARAM(dma_read_factor, "multiplier for dma reads"),
|
||||||
INIT_PARAM(dma_write_delay, "fixed delay for dma writes"),
|
INIT_PARAM(dma_write_delay, "fixed delay for dma writes"),
|
||||||
INIT_PARAM(dma_write_factor, "multiplier for dma writes"),
|
INIT_PARAM(dma_write_factor, "multiplier for dma writes"),
|
||||||
INIT_PARAM(dma_no_allocate, "Should we allocat on read in cache"),
|
|
||||||
INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"),
|
|
||||||
INIT_PARAM(intr_delay, "Interrupt Delay"),
|
|
||||||
|
|
||||||
INIT_PARAM(rx_delay, "Receive Delay"),
|
INIT_PARAM(rx_delay, "Receive Delay"),
|
||||||
INIT_PARAM(tx_delay, "Transmit Delay"),
|
INIT_PARAM(tx_delay, "Transmit Delay"),
|
||||||
|
@ -1678,31 +1539,22 @@ END_INIT_SIM_OBJECT_PARAMS(Device)
|
||||||
CREATE_SIM_OBJECT(Device)
|
CREATE_SIM_OBJECT(Device)
|
||||||
{
|
{
|
||||||
Device::Params *params = new Device::Params;
|
Device::Params *params = new Device::Params;
|
||||||
|
|
||||||
params->name = getInstanceName();
|
params->name = getInstanceName();
|
||||||
|
params->platform = platform;
|
||||||
params->clock = clock;
|
params->system = system;
|
||||||
|
|
||||||
params->mmu = mmu;
|
|
||||||
params->physmem = physmem;
|
|
||||||
params->configSpace = configspace;
|
params->configSpace = configspace;
|
||||||
params->configData = configdata;
|
params->configData = configdata;
|
||||||
params->plat = platform;
|
|
||||||
params->busNum = pci_bus;
|
params->busNum = pci_bus;
|
||||||
params->deviceNum = pci_dev;
|
params->deviceNum = pci_dev;
|
||||||
params->functionNum = pci_func;
|
params->functionNum = pci_func;
|
||||||
|
params->pio_delay = pio_latency;
|
||||||
|
params->intr_delay = intr_delay;
|
||||||
|
params->clock = clock;
|
||||||
|
|
||||||
params->hier = hier;
|
|
||||||
params->pio_bus = pio_bus;
|
|
||||||
params->header_bus = dma_bus;
|
|
||||||
params->payload_bus = payload_bus;
|
|
||||||
params->dma_read_delay = dma_read_delay;
|
params->dma_read_delay = dma_read_delay;
|
||||||
params->dma_read_factor = dma_read_factor;
|
params->dma_read_factor = dma_read_factor;
|
||||||
params->dma_write_delay = dma_write_delay;
|
params->dma_write_delay = dma_write_delay;
|
||||||
params->dma_write_factor = dma_write_factor;
|
params->dma_write_factor = dma_write_factor;
|
||||||
params->dma_no_allocate = dma_no_allocate;
|
|
||||||
params->pio_latency = pio_latency;
|
|
||||||
params->intr_delay = intr_delay;
|
|
||||||
|
|
||||||
params->tx_delay = tx_delay;
|
params->tx_delay = tx_delay;
|
||||||
params->rx_delay = rx_delay;
|
params->rx_delay = rx_delay;
|
||||||
|
|
44
dev/sinic.hh
44
dev/sinic.hh
|
@ -37,7 +37,6 @@
|
||||||
#include "dev/pcidev.hh"
|
#include "dev/pcidev.hh"
|
||||||
#include "dev/pktfifo.hh"
|
#include "dev/pktfifo.hh"
|
||||||
#include "dev/sinicreg.hh"
|
#include "dev/sinicreg.hh"
|
||||||
#include "mem/bus/bus.hh"
|
|
||||||
#include "sim/eventq.hh"
|
#include "sim/eventq.hh"
|
||||||
|
|
||||||
namespace Sinic {
|
namespace Sinic {
|
||||||
|
@ -90,10 +89,6 @@ class Base : public PciDev
|
||||||
|
|
||||||
class Device : public Base
|
class Device : public Base
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
Platform *plat;
|
|
||||||
PhysicalMemory *physmem;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Receive State Machine States */
|
/** Receive State Machine States */
|
||||||
enum RxState {
|
enum RxState {
|
||||||
|
@ -162,10 +157,6 @@ class Device : public Base
|
||||||
uint32_t ®Data32(Addr daddr) { return *(uint32_t *)®Data8(daddr); }
|
uint32_t ®Data32(Addr daddr) { return *(uint32_t *)®Data8(daddr); }
|
||||||
uint64_t ®Data64(Addr daddr) { return *(uint64_t *)®Data8(daddr); }
|
uint64_t ®Data64(Addr daddr) { return *(uint64_t *)®Data8(daddr); }
|
||||||
|
|
||||||
private:
|
|
||||||
Addr addr;
|
|
||||||
static const Addr size = Regs::Size;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RxState rxState;
|
RxState rxState;
|
||||||
PacketFifo rxFifo;
|
PacketFifo rxFifo;
|
||||||
|
@ -178,7 +169,7 @@ class Device : public Base
|
||||||
TxState txState;
|
TxState txState;
|
||||||
PacketFifo txFifo;
|
PacketFifo txFifo;
|
||||||
bool txFull;
|
bool txFull;
|
||||||
PacketPtr txPacket;
|
EthPacketPtr txPacket;
|
||||||
int txPacketOffset;
|
int txPacketOffset;
|
||||||
int txPacketBytes;
|
int txPacketBytes;
|
||||||
Addr txDmaAddr;
|
Addr txDmaAddr;
|
||||||
|
@ -218,7 +209,7 @@ class Device : public Base
|
||||||
/**
|
/**
|
||||||
* receive address filter
|
* receive address filter
|
||||||
*/
|
*/
|
||||||
bool rxFilter(const PacketPtr &packet);
|
bool rxFilter(const EthPacketPtr &packet);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* device configuration
|
* device configuration
|
||||||
|
@ -230,7 +221,7 @@ class Device : public Base
|
||||||
* device ethernet interface
|
* device ethernet interface
|
||||||
*/
|
*/
|
||||||
public:
|
public:
|
||||||
bool recvPacket(PacketPtr packet);
|
bool recvPacket(EthPacketPtr packet);
|
||||||
void transferDone();
|
void transferDone();
|
||||||
void setInterface(Interface *i) { assert(!interface); interface = i; }
|
void setInterface(Interface *i) { assert(!interface); interface = i; }
|
||||||
|
|
||||||
|
@ -238,12 +229,10 @@ class Device : public Base
|
||||||
* DMA parameters
|
* DMA parameters
|
||||||
*/
|
*/
|
||||||
protected:
|
protected:
|
||||||
void rxDmaCopy();
|
|
||||||
void rxDmaDone();
|
void rxDmaDone();
|
||||||
friend class EventWrapper<Device, &Device::rxDmaDone>;
|
friend class EventWrapper<Device, &Device::rxDmaDone>;
|
||||||
EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
|
EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
|
||||||
|
|
||||||
void txDmaCopy();
|
|
||||||
void txDmaDone();
|
void txDmaDone();
|
||||||
friend class EventWrapper<Device, &Device::txDmaDone>;
|
friend class EventWrapper<Device, &Device::txDmaDone>;
|
||||||
EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
|
EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
|
||||||
|
@ -261,26 +250,17 @@ class Device : public Base
|
||||||
void devIntrClear(uint32_t interrupts = Regs::Intr_All);
|
void devIntrClear(uint32_t interrupts = Regs::Intr_All);
|
||||||
void devIntrChangeMask(uint32_t newmask);
|
void devIntrChangeMask(uint32_t newmask);
|
||||||
|
|
||||||
/**
|
|
||||||
* PCI Configuration interface
|
|
||||||
*/
|
|
||||||
public:
|
|
||||||
virtual void writeConfig(int offset, int size, const uint8_t *data);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory Interface
|
* Memory Interface
|
||||||
*/
|
*/
|
||||||
public:
|
public:
|
||||||
virtual Fault read(MemReqPtr &req, uint8_t *data);
|
virtual Tick read(Packet &pkt);
|
||||||
virtual Fault write(MemReqPtr &req, const uint8_t *data);
|
virtual Tick write(Packet &pkt);
|
||||||
|
|
||||||
void prepareIO(int cpu, int index);
|
void prepareIO(int cpu, int index);
|
||||||
void prepareRead(int cpu, int index);
|
void prepareRead(int cpu, int index);
|
||||||
void prepareWrite(int cpu, int index);
|
void prepareWrite(int cpu, int index);
|
||||||
Fault iprRead(Addr daddr, int cpu, uint64_t &result);
|
// Fault iprRead(Addr daddr, int cpu, uint64_t &result);
|
||||||
Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data);
|
|
||||||
Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data);
|
|
||||||
Tick cacheAccess(MemReqPtr &req);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Statistics
|
* Statistics
|
||||||
|
@ -328,17 +308,8 @@ class Device : public Base
|
||||||
public:
|
public:
|
||||||
struct Params : public Base::Params
|
struct Params : public Base::Params
|
||||||
{
|
{
|
||||||
IntrControl *i;
|
|
||||||
PhysicalMemory *pmem;
|
|
||||||
Tick tx_delay;
|
Tick tx_delay;
|
||||||
Tick rx_delay;
|
Tick rx_delay;
|
||||||
HierParams *hier;
|
|
||||||
Bus *pio_bus;
|
|
||||||
Bus *header_bus;
|
|
||||||
Bus *payload_bus;
|
|
||||||
Tick pio_latency;
|
|
||||||
PhysicalMemory *physmem;
|
|
||||||
IntrControl *intctrl;
|
|
||||||
bool rx_filter;
|
bool rx_filter;
|
||||||
Net::EthAddr eaddr;
|
Net::EthAddr eaddr;
|
||||||
uint32_t rx_max_copy;
|
uint32_t rx_max_copy;
|
||||||
|
@ -352,7 +323,6 @@ class Device : public Base
|
||||||
Tick dma_read_factor;
|
Tick dma_read_factor;
|
||||||
Tick dma_write_delay;
|
Tick dma_write_delay;
|
||||||
Tick dma_write_factor;
|
Tick dma_write_factor;
|
||||||
bool dma_no_allocate;
|
|
||||||
bool rx_thread;
|
bool rx_thread;
|
||||||
bool tx_thread;
|
bool tx_thread;
|
||||||
bool rss;
|
bool rss;
|
||||||
|
@ -378,7 +348,7 @@ class Interface : public EtherInt
|
||||||
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) { dev->setInterface(this); }
|
||||||
|
|
||||||
virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); }
|
virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
|
||||||
virtual void sendDone() { dev->transferDone(); }
|
virtual void sendDone() { dev->transferDone(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -80,72 +80,65 @@ TsunamiCChip::read(Packet &pkt)
|
||||||
Addr regnum = (pkt.addr - pioAddr) >> 6;
|
Addr regnum = (pkt.addr - pioAddr) >> 6;
|
||||||
Addr daddr = (pkt.addr - pioAddr);
|
Addr daddr = (pkt.addr - pioAddr);
|
||||||
|
|
||||||
uint64_t *data64;
|
pkt.allocate();
|
||||||
|
|
||||||
switch (pkt.size) {
|
switch (pkt.size) {
|
||||||
|
|
||||||
case sizeof(uint64_t):
|
case sizeof(uint64_t):
|
||||||
if (!pkt.data) {
|
|
||||||
data64 = new uint64_t;
|
|
||||||
pkt.data = (uint8_t*)data64;
|
|
||||||
} else
|
|
||||||
data64 = (uint64_t*)pkt.data;
|
|
||||||
|
|
||||||
if (daddr & TSDEV_CC_BDIMS)
|
if (daddr & TSDEV_CC_BDIMS)
|
||||||
{
|
{
|
||||||
*data64 = dim[(daddr >> 4) & 0x3F];
|
pkt.set(dim[(daddr >> 4) & 0x3F]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (daddr & TSDEV_CC_BDIRS)
|
if (daddr & TSDEV_CC_BDIRS)
|
||||||
{
|
{
|
||||||
*data64 = dir[(daddr >> 4) & 0x3F];
|
pkt.set(dir[(daddr >> 4) & 0x3F]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(regnum) {
|
switch(regnum) {
|
||||||
case TSDEV_CC_CSR:
|
case TSDEV_CC_CSR:
|
||||||
*data64 = 0x0;
|
pkt.set(0x0);
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_MTR:
|
case TSDEV_CC_MTR:
|
||||||
panic("TSDEV_CC_MTR not implemeted\n");
|
panic("TSDEV_CC_MTR not implemeted\n");
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_MISC:
|
case TSDEV_CC_MISC:
|
||||||
*data64 = (ipint << 8) & 0xF | (itint << 4) & 0xF |
|
pkt.set((ipint << 8) & 0xF | (itint << 4) & 0xF |
|
||||||
(pkt.req->getCpuNum() & 0x3);
|
(pkt.req->getCpuNum() & 0x3));
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_AAR0:
|
case TSDEV_CC_AAR0:
|
||||||
case TSDEV_CC_AAR1:
|
case TSDEV_CC_AAR1:
|
||||||
case TSDEV_CC_AAR2:
|
case TSDEV_CC_AAR2:
|
||||||
case TSDEV_CC_AAR3:
|
case TSDEV_CC_AAR3:
|
||||||
*data64 = 0;
|
pkt.set(0);
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_DIM0:
|
case TSDEV_CC_DIM0:
|
||||||
*data64 = dim[0];
|
pkt.set(dim[0]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_DIM1:
|
case TSDEV_CC_DIM1:
|
||||||
*data64 = dim[1];
|
pkt.set(dim[1]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_DIM2:
|
case TSDEV_CC_DIM2:
|
||||||
*data64 = dim[2];
|
pkt.set(dim[2]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_DIM3:
|
case TSDEV_CC_DIM3:
|
||||||
*data64 = dim[3];
|
pkt.set(dim[3]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_DIR0:
|
case TSDEV_CC_DIR0:
|
||||||
*data64 = dir[0];
|
pkt.set(dir[0]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_DIR1:
|
case TSDEV_CC_DIR1:
|
||||||
*data64 = dir[1];
|
pkt.set(dir[1]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_DIR2:
|
case TSDEV_CC_DIR2:
|
||||||
*data64 = dir[2];
|
pkt.set(dir[2]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_DIR3:
|
case TSDEV_CC_DIR3:
|
||||||
*data64 = dir[3];
|
pkt.set(dir[3]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_DRIR:
|
case TSDEV_CC_DRIR:
|
||||||
*data64 = drir;
|
pkt.set(drir);
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_PRBEN:
|
case TSDEV_CC_PRBEN:
|
||||||
panic("TSDEV_CC_PRBEN not implemented\n");
|
panic("TSDEV_CC_PRBEN not implemented\n");
|
||||||
|
@ -163,10 +156,10 @@ TsunamiCChip::read(Packet &pkt)
|
||||||
panic("TSDEV_CC_MPRx not implemented\n");
|
panic("TSDEV_CC_MPRx not implemented\n");
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_IPIR:
|
case TSDEV_CC_IPIR:
|
||||||
*data64 = ipint;
|
pkt.set(ipint);
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_ITIR:
|
case TSDEV_CC_ITIR:
|
||||||
*data64 = itint;
|
pkt.set(itint);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("default in cchip read reached, accessing 0x%x\n");
|
panic("default in cchip read reached, accessing 0x%x\n");
|
||||||
|
@ -180,7 +173,7 @@ TsunamiCChip::read(Packet &pkt)
|
||||||
panic("invalid access size(?) for tsunami register!\n");
|
panic("invalid access size(?) for tsunami register!\n");
|
||||||
}
|
}
|
||||||
DPRINTF(Tsunami, "Tsunami CChip: read regnum=%#x size=%d data=%lld\n",
|
DPRINTF(Tsunami, "Tsunami CChip: read regnum=%#x size=%d data=%lld\n",
|
||||||
regnum, pkt.size, *data64);
|
regnum, pkt.size, pkt.get<uint64_t>());
|
||||||
|
|
||||||
pkt.result = Success;
|
pkt.result = Success;
|
||||||
return pioDelay;
|
return pioDelay;
|
||||||
|
@ -197,10 +190,9 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
Addr regnum = (pkt.addr - pioAddr) >> 6 ;
|
Addr regnum = (pkt.addr - pioAddr) >> 6 ;
|
||||||
|
|
||||||
|
|
||||||
uint64_t val = *(uint64_t *)pkt.data;
|
|
||||||
assert(pkt.size == sizeof(uint64_t));
|
assert(pkt.size == sizeof(uint64_t));
|
||||||
|
|
||||||
DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt.addr, val);
|
DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt.addr, pkt.get<uint64_t>());
|
||||||
|
|
||||||
bool supportedWrite = false;
|
bool supportedWrite = false;
|
||||||
|
|
||||||
|
@ -215,7 +207,7 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
|
|
||||||
olddim = dim[number];
|
olddim = dim[number];
|
||||||
olddir = dir[number];
|
olddir = dir[number];
|
||||||
dim[number] = val;
|
dim[number] = pkt.get<uint64_t>();
|
||||||
dir[number] = dim[number] & drir;
|
dir[number] = dim[number] & drir;
|
||||||
for(int x = 0; x < Tsunami::Max_CPUs; x++)
|
for(int x = 0; x < Tsunami::Max_CPUs; x++)
|
||||||
{
|
{
|
||||||
|
@ -252,7 +244,7 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
panic("TSDEV_CC_MTR write not implemented\n");
|
panic("TSDEV_CC_MTR write not implemented\n");
|
||||||
case TSDEV_CC_MISC:
|
case TSDEV_CC_MISC:
|
||||||
uint64_t ipreq;
|
uint64_t ipreq;
|
||||||
ipreq = (val >> 12) & 0xF;
|
ipreq = (pkt.get<uint64_t>() >> 12) & 0xF;
|
||||||
//If it is bit 12-15, this is an IPI post
|
//If it is bit 12-15, this is an IPI post
|
||||||
if (ipreq) {
|
if (ipreq) {
|
||||||
reqIPI(ipreq);
|
reqIPI(ipreq);
|
||||||
|
@ -261,7 +253,7 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
|
|
||||||
//If it is bit 8-11, this is an IPI clear
|
//If it is bit 8-11, this is an IPI clear
|
||||||
uint64_t ipintr;
|
uint64_t ipintr;
|
||||||
ipintr = (val >> 8) & 0xF;
|
ipintr = (pkt.get<uint64_t>() >> 8) & 0xF;
|
||||||
if (ipintr) {
|
if (ipintr) {
|
||||||
clearIPI(ipintr);
|
clearIPI(ipintr);
|
||||||
supportedWrite = true;
|
supportedWrite = true;
|
||||||
|
@ -269,14 +261,14 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
|
|
||||||
//If it is the 4-7th bit, clear the RTC interrupt
|
//If it is the 4-7th bit, clear the RTC interrupt
|
||||||
uint64_t itintr;
|
uint64_t itintr;
|
||||||
itintr = (val >> 4) & 0xF;
|
itintr = (pkt.get<uint64_t>() >> 4) & 0xF;
|
||||||
if (itintr) {
|
if (itintr) {
|
||||||
clearITI(itintr);
|
clearITI(itintr);
|
||||||
supportedWrite = true;
|
supportedWrite = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore NXMs
|
// ignore NXMs
|
||||||
if (val & 0x10000000)
|
if (pkt.get<uint64_t>() & 0x10000000)
|
||||||
supportedWrite = true;
|
supportedWrite = true;
|
||||||
|
|
||||||
if(!supportedWrite)
|
if(!supportedWrite)
|
||||||
|
@ -308,7 +300,7 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
|
|
||||||
olddim = dim[number];
|
olddim = dim[number];
|
||||||
olddir = dir[number];
|
olddir = dir[number];
|
||||||
dim[number] = val;
|
dim[number] = pkt.get<uint64_t>();
|
||||||
dir[number] = dim[number] & drir;
|
dir[number] = dim[number] & drir;
|
||||||
for(int x = 0; x < 64; x++)
|
for(int x = 0; x < 64; x++)
|
||||||
{
|
{
|
||||||
|
@ -358,13 +350,13 @@ TsunamiCChip::write(Packet &pkt)
|
||||||
case TSDEV_CC_MPR3:
|
case TSDEV_CC_MPR3:
|
||||||
panic("TSDEV_CC_MPRx write not implemented\n");
|
panic("TSDEV_CC_MPRx write not implemented\n");
|
||||||
case TSDEV_CC_IPIR:
|
case TSDEV_CC_IPIR:
|
||||||
clearIPI(val);
|
clearIPI(pkt.get<uint64_t>());
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_ITIR:
|
case TSDEV_CC_ITIR:
|
||||||
clearITI(val);
|
clearITI(pkt.get<uint64_t>());
|
||||||
break;
|
break;
|
||||||
case TSDEV_CC_IPIQ:
|
case TSDEV_CC_IPIQ:
|
||||||
reqIPI(val);
|
reqIPI(pkt.get<uint64_t>());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("default in cchip read reached, accessing 0x%x\n");
|
panic("default in cchip read reached, accessing 0x%x\n");
|
||||||
|
|
|
@ -447,65 +447,51 @@ TsunamiIO::read(Packet &pkt)
|
||||||
DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt.addr,
|
DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt.addr,
|
||||||
pkt.size, daddr);
|
pkt.size, daddr);
|
||||||
|
|
||||||
|
pkt.allocate();
|
||||||
uint8_t *data8;
|
|
||||||
uint64_t *data64;
|
|
||||||
|
|
||||||
if (pkt.size == sizeof(uint8_t)) {
|
if (pkt.size == sizeof(uint8_t)) {
|
||||||
|
|
||||||
if (!pkt.data) {
|
|
||||||
data8 = new uint8_t;
|
|
||||||
pkt.data = data8;
|
|
||||||
} else
|
|
||||||
data8 = pkt.data;
|
|
||||||
switch(daddr) {
|
switch(daddr) {
|
||||||
// PIC1 mask read
|
// PIC1 mask read
|
||||||
case TSDEV_PIC1_MASK:
|
case TSDEV_PIC1_MASK:
|
||||||
*data8 = ~mask1;
|
pkt.set(~mask1);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PIC2_MASK:
|
case TSDEV_PIC2_MASK:
|
||||||
*data8 = ~mask2;
|
pkt.set(~mask2);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PIC1_ISR:
|
case TSDEV_PIC1_ISR:
|
||||||
// !!! If this is modified 64bit case needs to be too
|
// !!! If this is modified 64bit case needs to be too
|
||||||
// Pal code has to do a 64 bit physical read because there is
|
// Pal code has to do a 64 bit physical read because there is
|
||||||
// no load physical byte instruction
|
// no load physical byte instruction
|
||||||
*data8 = picr;
|
pkt.set(picr);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PIC2_ISR:
|
case TSDEV_PIC2_ISR:
|
||||||
// PIC2 not implemnted... just return 0
|
// PIC2 not implemnted... just return 0
|
||||||
*data8 = 0x00;
|
pkt.set(0x00);
|
||||||
break;
|
break;
|
||||||
case TSDEV_TMR0_DATA:
|
case TSDEV_TMR0_DATA:
|
||||||
pitimer.counter0.read(data8);
|
pitimer.counter0.read(pkt.getPtr<uint8_t>());
|
||||||
break;
|
break;
|
||||||
case TSDEV_TMR1_DATA:
|
case TSDEV_TMR1_DATA:
|
||||||
pitimer.counter1.read(data8);
|
pitimer.counter1.read(pkt.getPtr<uint8_t>());
|
||||||
break;
|
break;
|
||||||
case TSDEV_TMR2_DATA:
|
case TSDEV_TMR2_DATA:
|
||||||
pitimer.counter2.read(data8);
|
pitimer.counter2.read(pkt.getPtr<uint8_t>());
|
||||||
break;
|
break;
|
||||||
case TSDEV_RTC_DATA:
|
case TSDEV_RTC_DATA:
|
||||||
rtc.readData(data8);
|
rtc.readData(pkt.getPtr<uint8_t>());
|
||||||
break;
|
break;
|
||||||
case TSDEV_CTRL_PORTB:
|
case TSDEV_CTRL_PORTB:
|
||||||
if (pitimer.counter2.outputHigh())
|
if (pitimer.counter2.outputHigh())
|
||||||
*data8 = PORTB_SPKR_HIGH;
|
pkt.set(PORTB_SPKR_HIGH);
|
||||||
else
|
else
|
||||||
*data8 = 0x00;
|
pkt.set(0x00);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("I/O Read - va%#x size %d\n", pkt.addr, pkt.size);
|
panic("I/O Read - va%#x size %d\n", pkt.addr, pkt.size);
|
||||||
}
|
}
|
||||||
} else if (pkt.size == sizeof(uint64_t)) {
|
} else if (pkt.size == sizeof(uint64_t)) {
|
||||||
if (!pkt.data) {
|
|
||||||
data64 = new uint64_t;
|
|
||||||
pkt.data = (uint8_t*)data64;
|
|
||||||
} else
|
|
||||||
data64 = (uint64_t*)pkt.data;
|
|
||||||
|
|
||||||
if (daddr == TSDEV_PIC1_ISR)
|
if (daddr == TSDEV_PIC1_ISR)
|
||||||
*data64 = picr;
|
pkt.set<uint64_t>(picr);
|
||||||
else
|
else
|
||||||
panic("I/O Read - invalid addr - va %#x size %d\n",
|
panic("I/O Read - invalid addr - va %#x size %d\n",
|
||||||
pkt.addr, pkt.size);
|
pkt.addr, pkt.size);
|
||||||
|
@ -524,20 +510,15 @@ TsunamiIO::write(Packet &pkt)
|
||||||
assert(pkt.result == Unknown);
|
assert(pkt.result == Unknown);
|
||||||
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
||||||
Addr daddr = pkt.addr - pioAddr;
|
Addr daddr = pkt.addr - pioAddr;
|
||||||
uint8_t val = *pkt.data;
|
|
||||||
|
|
||||||
#if TRACING_ON
|
|
||||||
uint64_t dt64 = val;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n",
|
DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n",
|
||||||
pkt.addr, pkt.size, pkt.addr & 0xfff, dt64);
|
pkt.addr, pkt.size, pkt.addr & 0xfff, (uint32_t)pkt.get<uint8_t>());
|
||||||
|
|
||||||
assert(pkt.size == sizeof(uint8_t));
|
assert(pkt.size == sizeof(uint8_t));
|
||||||
|
|
||||||
switch(daddr) {
|
switch(daddr) {
|
||||||
case TSDEV_PIC1_MASK:
|
case TSDEV_PIC1_MASK:
|
||||||
mask1 = ~(val);
|
mask1 = ~(pkt.get<uint8_t>());
|
||||||
if ((picr & mask1) && !picInterrupting) {
|
if ((picr & mask1) && !picInterrupting) {
|
||||||
picInterrupting = true;
|
picInterrupting = true;
|
||||||
tsunami->cchip->postDRIR(55);
|
tsunami->cchip->postDRIR(55);
|
||||||
|
@ -550,38 +531,38 @@ TsunamiIO::write(Packet &pkt)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TSDEV_PIC2_MASK:
|
case TSDEV_PIC2_MASK:
|
||||||
mask2 = val;
|
mask2 = pkt.get<uint8_t>();
|
||||||
//PIC2 Not implemented to interrupt
|
//PIC2 Not implemented to interrupt
|
||||||
break;
|
break;
|
||||||
case TSDEV_PIC1_ACK:
|
case TSDEV_PIC1_ACK:
|
||||||
// clear the interrupt on the PIC
|
// clear the interrupt on the PIC
|
||||||
picr &= ~(1 << (val & 0xF));
|
picr &= ~(1 << (pkt.get<uint8_t>() & 0xF));
|
||||||
if (!(picr & mask1))
|
if (!(picr & mask1))
|
||||||
tsunami->cchip->clearDRIR(55);
|
tsunami->cchip->clearDRIR(55);
|
||||||
break;
|
break;
|
||||||
case TSDEV_DMA1_MODE:
|
case TSDEV_DMA1_MODE:
|
||||||
mode1 = val;
|
mode1 = pkt.get<uint8_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_DMA2_MODE:
|
case TSDEV_DMA2_MODE:
|
||||||
mode2 = val;
|
mode2 = pkt.get<uint8_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_TMR0_DATA:
|
case TSDEV_TMR0_DATA:
|
||||||
pitimer.counter0.write(val);
|
pitimer.counter0.write(pkt.get<uint8_t>());
|
||||||
break;
|
break;
|
||||||
case TSDEV_TMR1_DATA:
|
case TSDEV_TMR1_DATA:
|
||||||
pitimer.counter1.write(val);
|
pitimer.counter1.write(pkt.get<uint8_t>());
|
||||||
break;
|
break;
|
||||||
case TSDEV_TMR2_DATA:
|
case TSDEV_TMR2_DATA:
|
||||||
pitimer.counter2.write(val);
|
pitimer.counter2.write(pkt.get<uint8_t>());
|
||||||
break;
|
break;
|
||||||
case TSDEV_TMR_CTRL:
|
case TSDEV_TMR_CTRL:
|
||||||
pitimer.writeControl(val);
|
pitimer.writeControl(pkt.get<uint8_t>());
|
||||||
break;
|
break;
|
||||||
case TSDEV_RTC_ADDR:
|
case TSDEV_RTC_ADDR:
|
||||||
rtc.writeAddr(val);
|
rtc.writeAddr(pkt.get<uint8_t>());
|
||||||
break;
|
break;
|
||||||
case TSDEV_RTC_DATA:
|
case TSDEV_RTC_DATA:
|
||||||
rtc.writeData(val);
|
rtc.writeData(pkt.get<uint8_t>());
|
||||||
break;
|
break;
|
||||||
case TSDEV_KBD:
|
case TSDEV_KBD:
|
||||||
case TSDEV_DMA1_CMND:
|
case TSDEV_DMA1_CMND:
|
||||||
|
@ -596,7 +577,7 @@ TsunamiIO::write(Packet &pkt)
|
||||||
case TSDEV_CTRL_PORTB:
|
case TSDEV_CTRL_PORTB:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("I/O Write - va%#x size %d data %#x\n", pkt.addr, pkt.size, val);
|
panic("I/O Write - va%#x size %d data %#x\n", pkt.addr, pkt.size, pkt.get<uint8_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
pkt.result = Success;
|
pkt.result = Success;
|
||||||
|
|
|
@ -70,75 +70,71 @@ TsunamiPChip::read(Packet &pkt)
|
||||||
assert(pkt.result == Unknown);
|
assert(pkt.result == Unknown);
|
||||||
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
||||||
|
|
||||||
|
|
||||||
pkt.time = curTick + pioDelay;
|
pkt.time = curTick + pioDelay;
|
||||||
|
pkt.allocate();
|
||||||
Addr daddr = (pkt.addr - pioAddr) >> 6;;
|
Addr daddr = (pkt.addr - pioAddr) >> 6;;
|
||||||
|
assert(pkt.size == sizeof(uint64_t));
|
||||||
|
|
||||||
uint64_t *data64;
|
|
||||||
|
|
||||||
if (!pkt.data) {
|
|
||||||
data64 = new uint64_t;
|
|
||||||
pkt.data = (uint8_t*)data64;
|
|
||||||
} else
|
|
||||||
data64 = (uint64_t*)pkt.data;
|
|
||||||
|
|
||||||
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size);
|
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size);
|
||||||
|
|
||||||
switch(daddr) {
|
switch(daddr) {
|
||||||
case TSDEV_PC_WSBA0:
|
case TSDEV_PC_WSBA0:
|
||||||
*data64 = wsba[0];
|
pkt.set(wsba[0]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_WSBA1:
|
case TSDEV_PC_WSBA1:
|
||||||
*data64 = wsba[1];
|
pkt.set(wsba[1]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_WSBA2:
|
case TSDEV_PC_WSBA2:
|
||||||
*data64 = wsba[2];
|
pkt.set(wsba[2]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_WSBA3:
|
case TSDEV_PC_WSBA3:
|
||||||
*data64 = wsba[3];
|
pkt.set(wsba[3]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_WSM0:
|
case TSDEV_PC_WSM0:
|
||||||
*data64 = wsm[0];
|
pkt.set(wsm[0]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_WSM1:
|
case TSDEV_PC_WSM1:
|
||||||
*data64 = wsm[1];
|
pkt.set(wsm[1]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_WSM2:
|
case TSDEV_PC_WSM2:
|
||||||
*data64 = wsm[2];
|
pkt.set(wsm[2]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_WSM3:
|
case TSDEV_PC_WSM3:
|
||||||
*data64 = wsm[3];
|
pkt.set(wsm[3]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_TBA0:
|
case TSDEV_PC_TBA0:
|
||||||
*data64 = tba[0];
|
pkt.set(tba[0]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_TBA1:
|
case TSDEV_PC_TBA1:
|
||||||
*data64 = tba[1];
|
pkt.set(tba[1]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_TBA2:
|
case TSDEV_PC_TBA2:
|
||||||
*data64 = tba[2];
|
pkt.set(tba[2]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_TBA3:
|
case TSDEV_PC_TBA3:
|
||||||
*data64 = tba[3];
|
pkt.set(tba[3]);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_PCTL:
|
case TSDEV_PC_PCTL:
|
||||||
*data64 = pctl;
|
pkt.set(pctl);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_PLAT:
|
case TSDEV_PC_PLAT:
|
||||||
panic("PC_PLAT not implemented\n");
|
panic("PC_PLAT not implemented\n");
|
||||||
case TSDEV_PC_RES:
|
case TSDEV_PC_RES:
|
||||||
panic("PC_RES not implemented\n");
|
panic("PC_RES not implemented\n");
|
||||||
case TSDEV_PC_PERROR:
|
case TSDEV_PC_PERROR:
|
||||||
*data64 = 0x00;
|
pkt.set((uint64_t)0x00);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_PERRMASK:
|
case TSDEV_PC_PERRMASK:
|
||||||
*data64 = 0x00;
|
pkt.set((uint64_t)0x00);
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_PERRSET:
|
case TSDEV_PC_PERRSET:
|
||||||
panic("PC_PERRSET not implemented\n");
|
panic("PC_PERRSET not implemented\n");
|
||||||
case TSDEV_PC_TLBIV:
|
case TSDEV_PC_TLBIV:
|
||||||
panic("PC_TLBIV not implemented\n");
|
panic("PC_TLBIV not implemented\n");
|
||||||
case TSDEV_PC_TLBIA:
|
case TSDEV_PC_TLBIA:
|
||||||
*data64 = 0x00; // shouldn't be readable, but linux
|
pkt.set((uint64_t)0x00); // shouldn't be readable, but linux
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_PMONCTL:
|
case TSDEV_PC_PMONCTL:
|
||||||
panic("PC_PMONCTL not implemented\n");
|
panic("PC_PMONCTL not implemented\n");
|
||||||
|
@ -161,50 +157,49 @@ TsunamiPChip::write(Packet &pkt)
|
||||||
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
||||||
Addr daddr = (pkt.addr - pioAddr) >> 6;
|
Addr daddr = (pkt.addr - pioAddr) >> 6;
|
||||||
|
|
||||||
uint64_t data64 = *(uint64_t *)pkt.data;
|
|
||||||
assert(pkt.size == sizeof(uint64_t));
|
assert(pkt.size == sizeof(uint64_t));
|
||||||
|
|
||||||
DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt.addr, pkt.size);
|
DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt.addr, pkt.size);
|
||||||
|
|
||||||
switch(daddr) {
|
switch(daddr) {
|
||||||
case TSDEV_PC_WSBA0:
|
case TSDEV_PC_WSBA0:
|
||||||
wsba[0] = data64;
|
wsba[0] = pkt.get<uint64_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_WSBA1:
|
case TSDEV_PC_WSBA1:
|
||||||
wsba[1] = data64;
|
wsba[1] = pkt.get<uint64_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_WSBA2:
|
case TSDEV_PC_WSBA2:
|
||||||
wsba[2] = data64;
|
wsba[2] = pkt.get<uint64_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_WSBA3:
|
case TSDEV_PC_WSBA3:
|
||||||
wsba[3] = data64;
|
wsba[3] = pkt.get<uint64_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_WSM0:
|
case TSDEV_PC_WSM0:
|
||||||
wsm[0] = data64;
|
wsm[0] = pkt.get<uint64_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_WSM1:
|
case TSDEV_PC_WSM1:
|
||||||
wsm[1] = data64;
|
wsm[1] = pkt.get<uint64_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_WSM2:
|
case TSDEV_PC_WSM2:
|
||||||
wsm[2] = data64;
|
wsm[2] = pkt.get<uint64_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_WSM3:
|
case TSDEV_PC_WSM3:
|
||||||
wsm[3] = data64;
|
wsm[3] = pkt.get<uint64_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_TBA0:
|
case TSDEV_PC_TBA0:
|
||||||
tba[0] = data64;
|
tba[0] = pkt.get<uint64_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_TBA1:
|
case TSDEV_PC_TBA1:
|
||||||
tba[1] = data64;
|
tba[1] = pkt.get<uint64_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_TBA2:
|
case TSDEV_PC_TBA2:
|
||||||
tba[2] = data64;
|
tba[2] = pkt.get<uint64_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_TBA3:
|
case TSDEV_PC_TBA3:
|
||||||
tba[3] = data64;
|
tba[3] = pkt.get<uint64_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_PCTL:
|
case TSDEV_PC_PCTL:
|
||||||
pctl = data64;
|
pctl = pkt.get<uint64_t>();
|
||||||
break;
|
break;
|
||||||
case TSDEV_PC_PLAT:
|
case TSDEV_PC_PLAT:
|
||||||
panic("PC_PLAT not implemented\n");
|
panic("PC_PLAT not implemented\n");
|
||||||
|
|
|
@ -116,23 +116,17 @@ Uart8250::read(Packet &pkt)
|
||||||
|
|
||||||
pkt.time = curTick + pioDelay;
|
pkt.time = curTick + pioDelay;
|
||||||
Addr daddr = pkt.addr - pioAddr;
|
Addr daddr = pkt.addr - pioAddr;
|
||||||
uint8_t *data;
|
pkt.allocate();
|
||||||
|
|
||||||
DPRINTF(Uart, " read register %#x\n", daddr);
|
DPRINTF(Uart, " read register %#x\n", daddr);
|
||||||
|
|
||||||
if (!pkt.data) {
|
|
||||||
data = new uint8_t;
|
|
||||||
pkt.data = data;
|
|
||||||
} else
|
|
||||||
data = pkt.data;
|
|
||||||
|
|
||||||
switch (daddr) {
|
switch (daddr) {
|
||||||
case 0x0:
|
case 0x0:
|
||||||
if (!(LCR & 0x80)) { // read byte
|
if (!(LCR & 0x80)) { // read byte
|
||||||
if (cons->dataAvailable())
|
if (cons->dataAvailable())
|
||||||
cons->in(*data);
|
cons->in(*pkt.getPtr<uint8_t>());
|
||||||
else {
|
else {
|
||||||
*data = 0;
|
pkt.set((uint8_t)0);
|
||||||
// A limited amount of these are ok.
|
// A limited amount of these are ok.
|
||||||
DPRINTF(Uart, "empty read of RX register\n");
|
DPRINTF(Uart, "empty read of RX register\n");
|
||||||
}
|
}
|
||||||
|
@ -147,7 +141,7 @@ Uart8250::read(Packet &pkt)
|
||||||
break;
|
break;
|
||||||
case 0x1:
|
case 0x1:
|
||||||
if (!(LCR & 0x80)) { // Intr Enable Register(IER)
|
if (!(LCR & 0x80)) { // Intr Enable Register(IER)
|
||||||
*data = IER;
|
pkt.set(IER);
|
||||||
} else { // DLM divisor latch MSB
|
} else { // DLM divisor latch MSB
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -156,17 +150,17 @@ Uart8250::read(Packet &pkt)
|
||||||
DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status);
|
DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status);
|
||||||
|
|
||||||
if (status & RX_INT) /* Rx data interrupt has a higher priority */
|
if (status & RX_INT) /* Rx data interrupt has a higher priority */
|
||||||
*data = IIR_RXID;
|
pkt.set(IIR_RXID);
|
||||||
else if (status & TX_INT)
|
else if (status & TX_INT)
|
||||||
*data = IIR_TXID;
|
pkt.set(IIR_TXID);
|
||||||
else
|
else
|
||||||
*data = IIR_NOPEND;
|
pkt.set(IIR_NOPEND);
|
||||||
|
|
||||||
//Tx interrupts are cleared on IIR reads
|
//Tx interrupts are cleared on IIR reads
|
||||||
status &= ~TX_INT;
|
status &= ~TX_INT;
|
||||||
break;
|
break;
|
||||||
case 0x3: // Line Control Register (LCR)
|
case 0x3: // Line Control Register (LCR)
|
||||||
*data = LCR;
|
pkt.set(LCR);
|
||||||
break;
|
break;
|
||||||
case 0x4: // Modem Control Register (MCR)
|
case 0x4: // Modem Control Register (MCR)
|
||||||
break;
|
break;
|
||||||
|
@ -177,13 +171,13 @@ Uart8250::read(Packet &pkt)
|
||||||
if (cons->dataAvailable())
|
if (cons->dataAvailable())
|
||||||
lsr = UART_LSR_DR;
|
lsr = UART_LSR_DR;
|
||||||
lsr |= UART_LSR_TEMT | UART_LSR_THRE;
|
lsr |= UART_LSR_TEMT | UART_LSR_THRE;
|
||||||
*data = lsr;
|
pkt.set(lsr);
|
||||||
break;
|
break;
|
||||||
case 0x6: // Modem Status Register (MSR)
|
case 0x6: // Modem Status Register (MSR)
|
||||||
*data = 0;
|
pkt.set((uint8_t)0);
|
||||||
break;
|
break;
|
||||||
case 0x7: // Scratch Register (SCR)
|
case 0x7: // Scratch Register (SCR)
|
||||||
*data = 0; // doesn't exist with at 8250.
|
pkt.set((uint8_t)0); // doesn't exist with at 8250.
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("Tried to access a UART port that doesn't exist\n");
|
panic("Tried to access a UART port that doesn't exist\n");
|
||||||
|
@ -207,14 +201,12 @@ Uart8250::write(Packet &pkt)
|
||||||
pkt.time = curTick + pioDelay;
|
pkt.time = curTick + pioDelay;
|
||||||
Addr daddr = pkt.addr - pioAddr;
|
Addr daddr = pkt.addr - pioAddr;
|
||||||
|
|
||||||
uint8_t *data = pkt.data;
|
DPRINTF(Uart, " write register %#x value %#x\n", daddr, pkt.get<uint8_t>());
|
||||||
|
|
||||||
DPRINTF(Uart, " write register %#x value %#x\n", daddr, *data);
|
|
||||||
|
|
||||||
switch (daddr) {
|
switch (daddr) {
|
||||||
case 0x0:
|
case 0x0:
|
||||||
if (!(LCR & 0x80)) { // write byte
|
if (!(LCR & 0x80)) { // write byte
|
||||||
cons->out(*data);
|
cons->out(pkt.get<uint8_t>());
|
||||||
platform->clearConsoleInt();
|
platform->clearConsoleInt();
|
||||||
status &= ~TX_INT;
|
status &= ~TX_INT;
|
||||||
if (UART_IER_THRI & IER)
|
if (UART_IER_THRI & IER)
|
||||||
|
@ -225,7 +217,7 @@ Uart8250::write(Packet &pkt)
|
||||||
break;
|
break;
|
||||||
case 0x1:
|
case 0x1:
|
||||||
if (!(LCR & 0x80)) { // Intr Enable Register(IER)
|
if (!(LCR & 0x80)) { // Intr Enable Register(IER)
|
||||||
IER = *data;
|
IER = pkt.get<uint8_t>();
|
||||||
if (UART_IER_THRI & IER)
|
if (UART_IER_THRI & IER)
|
||||||
{
|
{
|
||||||
DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n");
|
DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n");
|
||||||
|
@ -259,10 +251,10 @@ Uart8250::write(Packet &pkt)
|
||||||
case 0x2: // FIFO Control Register (FCR)
|
case 0x2: // FIFO Control Register (FCR)
|
||||||
break;
|
break;
|
||||||
case 0x3: // Line Control Register (LCR)
|
case 0x3: // Line Control Register (LCR)
|
||||||
LCR = *data;
|
LCR = pkt.get<uint8_t>();
|
||||||
break;
|
break;
|
||||||
case 0x4: // Modem Control Register (MCR)
|
case 0x4: // Modem Control Register (MCR)
|
||||||
if (*data == (UART_MCR_LOOP | 0x0A))
|
if (pkt.get<uint8_t>() == (UART_MCR_LOOP | 0x0A))
|
||||||
MCR = 0x9A;
|
MCR = 0x9A;
|
||||||
break;
|
break;
|
||||||
case 0x7: // Scratch Register (SCR)
|
case 0x7: // Scratch Register (SCR)
|
||||||
|
|
|
@ -44,13 +44,13 @@
|
||||||
* bit 2:1 ID of highest priority interrupt
|
* bit 2:1 ID of highest priority interrupt
|
||||||
* bit 7:3 zeroes
|
* bit 7:3 zeroes
|
||||||
*/
|
*/
|
||||||
#define IIR_NOPEND 0x1
|
const uint8_t IIR_NOPEND = 0x1;
|
||||||
|
|
||||||
// Interrupt IDs
|
// Interrupt IDs
|
||||||
#define IIR_MODEM 0x00 /* Modem Status (lowest priority) */
|
const uint8_t IIR_MODEM = 0x00; /* Modem Status (lowest priority) */
|
||||||
#define IIR_TXID 0x02 /* Tx Data */
|
const uint8_t IIR_TXID = 0x02; /* Tx Data */
|
||||||
#define IIR_RXID 0x04 /* Rx Data */
|
const uint8_t IIR_RXID = 0x04; /* Rx Data */
|
||||||
#define IIR_LINE 0x06 /* Rx Line Status (highest priority)*/
|
const uint8_t IIR_LINE = 0x06; /* Rx Line Status (highest priority)*/
|
||||||
|
|
||||||
class SimConsole;
|
class SimConsole;
|
||||||
class Platform;
|
class Platform;
|
||||||
|
|
121
mem/packet.hh
121
mem/packet.hh
|
@ -76,6 +76,26 @@ class Coherence{};
|
||||||
*/
|
*/
|
||||||
struct Packet
|
struct Packet
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
/** A pointer to the data being transfered. It can be differnt sizes
|
||||||
|
at each level of the heirarchy so it belongs in the packet,
|
||||||
|
not request. This may or may not be populated when a responder recieves
|
||||||
|
the packet. If not populated it memory should be allocated.
|
||||||
|
*/
|
||||||
|
PacketDataPtr data;
|
||||||
|
|
||||||
|
/** Is the data pointer set to a value that shouldn't be freed when the
|
||||||
|
* packet is destroyed? */
|
||||||
|
bool staticData;
|
||||||
|
/** The data pointer points to a value that should be freed when the packet
|
||||||
|
* is destroyed. */
|
||||||
|
bool dynamicData;
|
||||||
|
/** the data pointer points to an array (thus delete [] ) needs to be called
|
||||||
|
* on it rather than simply delete.*/
|
||||||
|
bool arrayData;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
/** The address of the request, could be virtual or physical (depending on
|
/** The address of the request, could be virtual or physical (depending on
|
||||||
cache configurations). */
|
cache configurations). */
|
||||||
Addr addr;
|
Addr addr;
|
||||||
|
@ -95,16 +115,7 @@ struct Packet
|
||||||
void *senderState; // virtual base opaque,
|
void *senderState; // virtual base opaque,
|
||||||
// assert(dynamic_cast<Foo>) etc.
|
// assert(dynamic_cast<Foo>) etc.
|
||||||
|
|
||||||
/** A pointer to the data being transfered. It can be differnt sizes
|
/** Indicates the size of the request. */
|
||||||
at each level of the heirarchy so it belongs in the packet,
|
|
||||||
not request.
|
|
||||||
This pointer may be NULL! If it isn't null when received by the producer
|
|
||||||
of data it refers to memory that has not been dynamically allocated.
|
|
||||||
Otherwise the producer should simply allocate dynamic memory to use.
|
|
||||||
*/
|
|
||||||
PacketDataPtr data;
|
|
||||||
|
|
||||||
/** Indicates the size of the request. */
|
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
/** A index of the source of the transaction. */
|
/** A index of the source of the transaction. */
|
||||||
|
@ -130,10 +141,96 @@ struct Packet
|
||||||
short getDest() const { return dest; }
|
short getDest() const { return dest; }
|
||||||
|
|
||||||
Packet()
|
Packet()
|
||||||
: result(Unknown)
|
: data(NULL), staticData(false), dynamicData(false), arrayData(false),
|
||||||
|
result(Unknown)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void reset() { result = Unknown; }
|
~Packet()
|
||||||
|
{ deleteData(); }
|
||||||
|
|
||||||
|
|
||||||
|
/** Minimally reset a packet so something like simple cpu can reuse it. */
|
||||||
|
void reset() {
|
||||||
|
result = Unknown;
|
||||||
|
if (dynamicData) {
|
||||||
|
deleteData();
|
||||||
|
dynamicData = false;
|
||||||
|
arrayData = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the data pointer to the following value that should not be freed. */
|
||||||
|
template <typename T>
|
||||||
|
void dataStatic(T *p) {
|
||||||
|
assert(!dynamicData);
|
||||||
|
data = (PacketDataPtr)p;
|
||||||
|
staticData = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the data pointer to a value that should have delete [] called on it.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
void dataDynamicArray(T *p) {
|
||||||
|
assert(!staticData && !dynamicData);
|
||||||
|
data = (PacketDataPtr)p;
|
||||||
|
dynamicData = true;
|
||||||
|
arrayData = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** set the data pointer to a value that should have delete called on it. */
|
||||||
|
template <typename T>
|
||||||
|
void dataDynamic(T *p) {
|
||||||
|
assert(!staticData && !dynamicData);
|
||||||
|
data = (PacketDataPtr)p;
|
||||||
|
dynamicData = true;
|
||||||
|
arrayData = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** return the value of what is pointed to in the packet. */
|
||||||
|
template <typename T>
|
||||||
|
T get() {
|
||||||
|
assert(staticData || dynamicData);
|
||||||
|
assert(sizeof(T) <= size);
|
||||||
|
return *(T*)data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** get a pointer to the data ptr. */
|
||||||
|
template <typename T>
|
||||||
|
T* getPtr() {
|
||||||
|
assert(staticData || dynamicData);
|
||||||
|
return (T*)data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** set the value in the data pointer to v. */
|
||||||
|
template <typename T>
|
||||||
|
void set(T v) {
|
||||||
|
assert(sizeof(T) <= size);
|
||||||
|
*(T*)data = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** delete the data pointed to in the data pointer. Ok to call to matter how
|
||||||
|
* data was allocted. */
|
||||||
|
void deleteData() {
|
||||||
|
assert(staticData || dynamicData);
|
||||||
|
if (staticData)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (arrayData)
|
||||||
|
delete [] data;
|
||||||
|
else
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** If there isn't data in the packet, allocate some. */
|
||||||
|
void allocate() {
|
||||||
|
if (data)
|
||||||
|
return;
|
||||||
|
assert(!staticData);
|
||||||
|
dynamicData = true;
|
||||||
|
arrayData = true;
|
||||||
|
data = new uint8_t[size];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__MEM_PACKET_HH
|
#endif //__MEM_PACKET_HH
|
||||||
|
|
|
@ -148,10 +148,12 @@ PhysicalMemory::doFunctionalAccess(Packet &pkt)
|
||||||
|
|
||||||
switch (pkt.cmd) {
|
switch (pkt.cmd) {
|
||||||
case Read:
|
case Read:
|
||||||
memcpy(pkt.data, pmem_addr + pkt.addr - base_addr, pkt.size);
|
memcpy(pkt.getPtr<uint8_t>(), pmem_addr + pkt.addr - base_addr,
|
||||||
|
pkt.size);
|
||||||
break;
|
break;
|
||||||
case Write:
|
case Write:
|
||||||
memcpy(pmem_addr + pkt.addr - base_addr, pkt.data, pkt.size);
|
memcpy(pmem_addr + pkt.addr - base_addr, pkt.getPtr<uint8_t>(),
|
||||||
|
pkt.size);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("unimplemented");
|
panic("unimplemented");
|
||||||
|
|
|
@ -45,7 +45,7 @@ Port::blobHelper(Addr addr, uint8_t *p, int size, Command cmd)
|
||||||
!gen.done(); gen.next()) {
|
!gen.done(); gen.next()) {
|
||||||
req.setPaddr(pkt.addr = gen.addr());
|
req.setPaddr(pkt.addr = gen.addr());
|
||||||
req.setSize(pkt.size = gen.size());
|
req.setSize(pkt.size = gen.size());
|
||||||
pkt.data = p;
|
pkt.dataStatic(p);
|
||||||
sendFunctional(pkt);
|
sendFunctional(pkt);
|
||||||
p += gen.size();
|
p += gen.size();
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,14 +67,10 @@ class EtherDevBase(PciDevice):
|
||||||
|
|
||||||
clock = Param.Clock('0ns', "State machine processor frequency")
|
clock = Param.Clock('0ns', "State machine processor frequency")
|
||||||
|
|
||||||
physmem = Param.PhysicalMemory(Parent.any, "Physical Memory")
|
|
||||||
|
|
||||||
payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload")
|
|
||||||
dma_read_delay = Param.Latency('0us', "fixed delay for dma reads")
|
dma_read_delay = Param.Latency('0us', "fixed delay for dma reads")
|
||||||
dma_read_factor = Param.Latency('0us', "multiplier for dma reads")
|
dma_read_factor = Param.Latency('0us', "multiplier for dma reads")
|
||||||
dma_write_delay = Param.Latency('0us', "fixed delay for dma writes")
|
dma_write_delay = Param.Latency('0us', "fixed delay for dma writes")
|
||||||
dma_write_factor = Param.Latency('0us', "multiplier for dma writes")
|
dma_write_factor = Param.Latency('0us', "multiplier for dma writes")
|
||||||
dma_no_allocate = Param.Bool(True, "Should we allocate cache on read")
|
|
||||||
|
|
||||||
rx_delay = Param.Latency('1us', "Receive Delay")
|
rx_delay = Param.Latency('1us', "Receive Delay")
|
||||||
tx_delay = Param.Latency('1us', "Transmit Delay")
|
tx_delay = Param.Latency('1us', "Transmit Delay")
|
||||||
|
@ -92,6 +88,7 @@ class NSGigE(EtherDevBase):
|
||||||
|
|
||||||
dma_data_free = Param.Bool(False, "DMA of Data is free")
|
dma_data_free = Param.Bool(False, "DMA of Data is free")
|
||||||
dma_desc_free = Param.Bool(False, "DMA of Descriptors 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")
|
||||||
|
|
||||||
|
|
||||||
class NSGigEInt(EtherInt):
|
class NSGigEInt(EtherInt):
|
||||||
|
|
Loading…
Reference in a new issue