dev/alpha_console.cc
dev/baddev.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/io_device.cc
dev/isa_fake.cc
+ dev/ns_gige.cc
dev/pciconfigall.cc
dev/pcidev.cc
+ dev/pcifake.cc
+ dev/pktfifo.cc
dev/platform.cc
dev/simconsole.cc
dev/simple_disk.cc
+ dev/sinic.cc
dev/tsunami.cc
dev/tsunami_cchip.cc
dev/tsunami_io.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':
full_system_sources += Split('''
{
protected:
friend class IpPtr;
- PacketPtr p;
+ EthPacketPtr p;
public:
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; }
const EthHdr &operator*() 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; }
- PacketPtr packet() { return p; }
+ const EthPacketPtr packet() const { return p; }
+ EthPacketPtr packet() { return p; }
bool operator!() const { return !p; }
operator bool() const { return p; }
};
protected:
friend class TcpPtr;
friend class UdpPtr;
- PacketPtr p;
+ EthPacketPtr p;
const IpHdr *h() const
{ return (const 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;
if (eth->type() == ETH_TYPE_IP)
public:
IpPtr() {}
- IpPtr(const PacketPtr &ptr) { set(ptr); }
+ IpPtr(const EthPacketPtr &ptr) { set(ptr); }
IpPtr(const EthPtr &ptr) { set(ptr.p); }
IpPtr(const IpPtr &ptr) : p(ptr.p) { }
const IpHdr &operator*() 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 IpPtr &ptr) { p = ptr.p; return *this; }
- const PacketPtr packet() const { return p; }
- PacketPtr packet() { return p; }
+ const EthPacketPtr packet() const { return p; }
+ EthPacketPtr packet() { return p; }
bool operator!() const { return !p; }
operator bool() const { return p; }
operator bool() { return p; }
class TcpPtr
{
protected:
- PacketPtr p;
+ EthPacketPtr p;
int off;
const TcpHdr *h() const { return (const 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)
{
if (ptr->proto() == IP_PROTO_TCP)
const TcpPtr &operator=(const IpPtr &i) { set(i); return *this; }
const TcpPtr &operator=(const TcpPtr &t) { set(t.p, t.off); return *this; }
- const PacketPtr packet() const { return p; }
- PacketPtr packet() { return p; }
+ const EthPacketPtr packet() const { return p; }
+ EthPacketPtr packet() { return p; }
bool operator!() const { return !p; }
operator bool() const { return p; }
operator bool() { return p; }
class UdpPtr
{
protected:
- PacketPtr p;
+ EthPacketPtr p;
int off;
const UdpHdr *h() const { return (const 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)
{
if (ptr->proto() == IP_PROTO_UDP)
const UdpPtr &operator=(const IpPtr &i) { set(i); return *this; }
const UdpPtr &operator=(const UdpPtr &t) { set(t.p, t.off); return *this; }
- const PacketPtr packet() const { return p; }
- PacketPtr packet() { return p; }
+ const EthPacketPtr packet() const { return p; }
+ EthPacketPtr packet() { return p; }
bool operator!() const { return !p; }
operator bool() const { return p; }
operator bool() { return p; }
--- /dev/null
+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)
+
BAR3Size = '4B'
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):
raw_image = RawDiskImage(image_file=linux_image, read_only=True)
fb = BadDevice(pio_addr=0x801fc0003d0, devicename='FrameBuffer')
io = TsunamiIO(pio_addr=0x801fc000000)
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)
-# etherint = NSGigEInt(device=Parent.ethernet)
+# etherint = SinicInt(device=Parent.ethernet)
console = AlphaConsole(pio_addr=0x80200000000, disk=Parent.simple_disk)
# bridge = PciFake(configdata=BridgePciData(), pci_bus=0, pci_dev=2, pci_func=0)
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)
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)
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)
intrctrl = IntrControl()
cpu = SimpleCPU(mem=Parent.magicbus)
sim_console = SimConsole(listener=ConsoleListener(port=3456))
- kernel = binary('vmlinux')
+ kernel = '/z/saidi/work/m5.newmem/build/vmlinux'
pal = binary('ts_osfpal')
console = binary('console')
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.dtb = AlphaDTB()
BaseCPU.system = Parent.any
-class TsunamiRoot(Root):
+class TsunamiRoot(System):
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')))
+
void
CPUExecContext::delVirtPort(VirtualPort *vp)
{
- assert(!vp->nullExecContext());
+// assert(!vp->nullExecContext());
delete vp->getPeer();
delete vp;
}
#if SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE
ifetch_req = new Request(true);
ifetch_req->setAsid(0);
+ // @todo fix me and get the real cpu iD!!!
+ ifetch_req->setCpuNum(0);
ifetch_req->setSize(sizeof(MachInst));
ifetch_pkt = new Packet;
ifetch_pkt->cmd = Read;
- ifetch_pkt->data = (uint8_t *)&inst;
+ ifetch_pkt->dataStatic(&inst);
ifetch_pkt->req = ifetch_req;
ifetch_pkt->size = sizeof(MachInst);
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_pkt = new Packet;
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_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_pkt = new Packet;
data_write_pkt->cmd = Write;
// Fault fault = xc->read(memReq,data);
// Not sure what to check for no fault...
if (data_read_pkt->result == Success) {
- memcpy(&data, data_read_pkt->data, sizeof(T));
+ data = data_read_pkt->get<T>();
}
if (traceData) {
// Need to find a way to not duplicate code above.
if (data_read_pkt->result == Success) {
- memcpy(&data, data_read_pkt->data, sizeof(T));
+ data = data_read_pkt->get<T>();
}
if (traceData) {
data_write_pkt = new Packet;
data_write_pkt->cmd = Write;
data_write_pkt->req = data_write_req;
- data_write_pkt->data = new uint8_t[64];
- memcpy(data_write_pkt->data, &data, sizeof(T));
+ data_write_pkt->allocate();
+ data_write_pkt->set(data);
#else
data_write_pkt->reset();
- data_write_pkt->data = (uint8_t *)&data;
+ data_write_pkt->dataStatic(&data);
#endif
data_write_pkt->addr = data_write_req->getPaddr();
data_write_pkt->size = sizeof(T);
scheduleTickEvent(1);
// Copy the icache data into the instruction itself.
- memcpy(&inst, pkt->data, sizeof(inst));
+ inst = pkt->get<MachInst>();
delete pkt;
break;
// current instruction
MachInst inst;
+ // Static data storage
+ TheISA::IntReg dataReg;
+
#if SIMPLE_CPU_MEM_TIMING
Packet *retry_pkt;
#elif SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE
pkt.time = curTick + pioDelay;
Addr daddr = pkt.addr - pioAddr;
- uint32_t *data32;
- uint64_t *data64;
+ pkt.allocate();
switch (pkt.size)
{
case sizeof(uint32_t):
- if (!pkt.data) {
- data32 = new uint32_t;
- pkt.data = (uint8_t*)data32;
- } else
- data32 = (uint32_t*)pkt.data;
-
switch (daddr)
{
case offsetof(AlphaAccess, last_offset):
- *data32 = alphaAccess->last_offset;
+ pkt.set(alphaAccess->last_offset);
break;
case offsetof(AlphaAccess, version):
- *data32 = alphaAccess->version;
+ pkt.set(alphaAccess->version);
break;
case offsetof(AlphaAccess, numCPUs):
- *data32 = alphaAccess->numCPUs;
+ pkt.set(alphaAccess->numCPUs);
break;
case offsetof(AlphaAccess, intrClockFrequency):
- *data32 = alphaAccess->intrClockFrequency;
+ pkt.set(alphaAccess->intrClockFrequency);
break;
default:
/* Old console code read in everyting as a 32bit int
*/
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;
case sizeof(uint64_t):
- if (!pkt.data) {
- data64 = new uint64_t;
- pkt.data = (uint8_t*)data64;
- } else
- data64 = (uint64_t*)pkt.data;
switch (daddr)
{
case offsetof(AlphaAccess, inputChar):
- *data64 = console->console_in();
+ pkt.set(console->console_in());
break;
case offsetof(AlphaAccess, cpuClock):
- *data64 = alphaAccess->cpuClock;
+ pkt.set(alphaAccess->cpuClock);
break;
case offsetof(AlphaAccess, mem_size):
- *data64 = alphaAccess->mem_size;
+ pkt.set(alphaAccess->mem_size);
break;
case offsetof(AlphaAccess, kernStart):
- *data64 = alphaAccess->kernStart;
+ pkt.set(alphaAccess->kernStart);
break;
case offsetof(AlphaAccess, kernEnd):
- *data64 = alphaAccess->kernEnd;
+ pkt.set(alphaAccess->kernEnd);
break;
case offsetof(AlphaAccess, entryPoint):
- *data64 = alphaAccess->entryPoint;
+ pkt.set(alphaAccess->entryPoint);
break;
case offsetof(AlphaAccess, diskUnit):
- *data64 = alphaAccess->diskUnit;
+ pkt.set(alphaAccess->diskUnit);
break;
case offsetof(AlphaAccess, diskCount):
- *data64 = alphaAccess->diskCount;
+ pkt.set(alphaAccess->diskCount);
break;
case offsetof(AlphaAccess, diskPAddr):
- *data64 = alphaAccess->diskPAddr;
+ pkt.set(alphaAccess->diskPAddr);
break;
case offsetof(AlphaAccess, diskBlock):
- *data64 = alphaAccess->diskBlock;
+ pkt.set(alphaAccess->diskBlock);
break;
case offsetof(AlphaAccess, diskOperation):
- *data64 = alphaAccess->diskOperation;
+ pkt.set(alphaAccess->diskOperation);
break;
case offsetof(AlphaAccess, outputChar):
- *data64 = alphaAccess->outputChar;
+ pkt.set(alphaAccess->outputChar);
break;
default:
int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
sizeof(alphaAccess->cpuStack[0]);
if (cpunum >= 0 && cpunum < 64)
- *data64 = alphaAccess->cpuStack[cpunum];
+ pkt.set(alphaAccess->cpuStack[cpunum]);
else
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;
default:
pkt.result = BadAddress;
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
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));
switch (daddr) {
{ devlist.push_back(dev); }
bool
-EtherBus::send(EtherInt *sndr, PacketPtr &pkt)
+EtherBus::send(EtherInt *sndr, EthPacketPtr &pkt)
{
if (busy()) {
DPRINTF(Ethernet, "ethernet packet not sent, bus busy\n", curTick);
};
DoneEvent event;
- PacketPtr packet;
+ EthPacketPtr packet;
EtherInt *sender;
EtherDump *dump;
void txDone();
void reg(EtherInt *dev);
bool busy() const { return (bool)packet; }
- bool send(EtherInt *sender, PacketPtr &packet);
+ bool send(EtherInt *sender, EthPacketPtr &packet);
};
#endif // __ETHERBUS_H__
}
void
-EtherDump::dumpPacket(PacketPtr &packet)
+EtherDump::dumpPacket(EthPacketPtr &packet)
{
pcap_pkthdr pkthdr;
pkthdr.seconds = curtime + (curTick / Clock::Int::s);
private:
std::ofstream stream;
const int maxlen;
- void dumpPacket(PacketPtr &packet);
+ void dumpPacket(EthPacketPtr &packet);
void init();
Tick curtime;
public:
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__
void recvDone() { peer->sendDone(); }
virtual void sendDone() = 0;
- bool sendPacket(PacketPtr packet)
+ bool sendPacket(EthPacketPtr packet)
{ return peer ? peer->recvPacket(packet) : true; }
- virtual bool recvPacket(PacketPtr packet) = 0;
+ virtual bool recvPacket(EthPacketPtr packet) = 0;
};
#endif // __DEV_ETHERINT_HH__
}
void
-EtherLink::Link::txComplete(PacketPtr packet)
+EtherLink::Link::txComplete(EthPacketPtr packet)
{
DPRINTF(Ethernet, "packet received: len=%d\n", packet->length);
DDUMP(EthernetData, packet->data, packet->length);
{
protected:
EtherLink::Link *link;
- PacketPtr packet;
+ EthPacketPtr packet;
public:
// non-scheduling version for createForUnserialize()
LinkDelayEvent();
- LinkDelayEvent(EtherLink::Link *link, PacketPtr pkt, Tick when);
+ LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt, Tick when);
void process();
}
bool
-EtherLink::Link::transmit(PacketPtr pkt)
+EtherLink::Link::transmit(EthPacketPtr pkt)
{
if (busy()) {
DPRINTF(Ethernet, "packet not sent, link busy\n");
bool packet_exists;
paramIn(cp, section, base + ".packet_exists", packet_exists);
if (packet_exists) {
- packet = new PacketData(16384);
+ packet = new EthPacketData(16384);
packet->unserialize(base + ".packet", cp, section);
}
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)
{
setFlags(AutoSerialize);
link = parent->link[number];
- packet = new PacketData(16384);
+ packet = new EthPacketData(16384);
packet->unserialize("packet", cp, section);
}
/*
* Transfer is complete
*/
- PacketPtr packet;
+ EthPacketPtr packet;
void txDone();
typedef EventWrapper<Link, &Link::txDone> DoneEvent;
friend void DoneEvent::process();
DoneEvent doneEvent;
friend class LinkDelayEvent;
- void txComplete(PacketPtr packet);
+ void txComplete(EthPacketPtr packet);
public:
Link(const std::string &name, EtherLink *p, int num,
const std::string name() const { return objName; }
bool busy() const { return (bool)packet; }
- bool transmit(PacketPtr packet);
+ bool transmit(EthPacketPtr packet);
void setTxInt(Interface *i) { assert(!txint); txint = i; }
void setRxInt(Interface *i) { assert(!rxint); rxint = i; }
public:
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(); }
};
using namespace std;
void
-PacketData::serialize(const string &base, ostream &os)
+EthPacketData::serialize(const string &base, ostream &os)
{
paramOut(os, base + ".length", length);
paramOut(os, base + ".slack", slack);
}
void
-PacketData::unserialize(const string &base, Checkpoint *cp,
+EthPacketData::unserialize(const string &base, Checkpoint *cp,
const string §ion)
{
paramIn(cp, section, base + ".length", length);
* Reference counted class containing ethernet packet data
*/
class Checkpoint;
-class PacketData : public RefCounted
+class EthPacketData : public RefCounted
{
public:
/*
int slack;
public:
- PacketData() : data(NULL), length(0), slack(0) { }
- explicit PacketData(size_t size)
+ EthPacketData() : data(NULL), length(0), slack(0) { }
+ explicit EthPacketData(size_t size)
: 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) { }
- ~PacketData() { if (data) delete [] data; }
+ ~EthPacketData() { if (data) delete [] data; }
public:
void serialize(const std::string &base, std::ostream &os);
const std::string §ion);
};
-typedef RefCountingPtr<PacketData> PacketPtr;
+typedef RefCountingPtr<EthPacketData> EthPacketPtr;
#endif // __ETHERPKT_HH__
}
bool
-EtherTap::recvPacket(PacketPtr packet)
+EtherTap::recvPacket(EthPacketPtr packet)
{
if (dump)
dump->dump(packet);
}
while (data_len != 0 && buffer_offset >= data_len + sizeof(u_int32_t)) {
- PacketPtr packet;
- packet = new PacketData(data_len);
+ EthPacketPtr packet;
+ packet = new EthPacketData(data_len);
packet->length = data_len;
memcpy(packet->data, data, data_len);
if (packetBuffer.empty())
return;
- PacketPtr packet = packetBuffer.front();
+ EthPacketPtr packet = packetBuffer.front();
if (sendPacket(packet)) {
if (dump)
dump->dump(packet);
protected:
std::string device;
- std::queue<PacketPtr> packetBuffer;
+ std::queue<EthPacketPtr> packetBuffer;
void process(int revent);
- void enqueue(PacketData *packet);
+ void enqueue(EthPacketData *packet);
void retransmit();
/*
EtherTap(const std::string &name, EtherDump *dump, int port, int bufsz);
virtual ~EtherTap();
- virtual bool recvPacket(PacketPtr packet);
+ virtual bool recvPacket(EthPacketPtr packet);
virtual void sendDone();
virtual void serialize(std::ostream &os);
IdeRegType reg_type;
int disk;
- uint8_t *data8 = 0 ;
- uint16_t *data16 = 0;
- uint32_t *data32 = 0;
-
- 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:
+ pkt.time = curTick + pioDelay;
+ pkt.allocate();
+ if (pkt.size != 1 && pkt.size != 2 && pkt.size !=4)
panic("Bad IDE read size: %d\n", pkt.size);
- }
parseAddr(pkt.addr, offset, channel, reg_type);
case BMI_BLOCK:
switch (pkt.size) {
case sizeof(uint8_t):
- *data8 = bmi_regs.data[offset];
+ pkt.set(bmi_regs.data[offset]);
break;
case sizeof(uint16_t):
- *data16 = *(uint16_t*)&bmi_regs.data[offset];
+ pkt.set(*(uint16_t*)&bmi_regs.data[offset]);
break;
case sizeof(uint32_t):
- *data32 = *(uint32_t*)&bmi_regs.data[offset];
+ pkt.set(*(uint32_t*)&bmi_regs.data[offset]);
break;
default:
panic("IDE read of BMI reg invalid size: %#x\n", pkt.size);
case CONTROL_BLOCK:
disk = getDisk(channel);
- if (disks[disk] == NULL)
+ if (disks[disk] == NULL) {
+ pkt.set<uint8_t>(0);
break;
+ }
switch (offset) {
case DATA_OFFSET:
switch (pkt.size) {
case sizeof(uint16_t):
- disks[disk]->read(offset, reg_type, (uint8_t*)data16);
+ disks[disk]->read(offset, reg_type, pkt.getPtr<uint8_t>());
break;
case sizeof(uint32_t):
- disks[disk]->read(offset, reg_type, (uint8_t*)data16);
- disks[disk]->read(offset, reg_type, (uint8_t*)(data16 + sizeof(uint16_t)));
+ disks[disk]->read(offset, reg_type, pkt.getPtr<uint8_t>());
+ disks[disk]->read(offset, reg_type,
+ pkt.getPtr<uint8_t>() + sizeof(uint16_t));
break;
default:
break;
default:
if (pkt.size == sizeof(uint8_t)) {
- disks[disk]->read(offset, reg_type, data8);
+ disks[disk]->read(offset, reg_type, pkt.getPtr<uint8_t>());
} else
panic("IDE read of command reg of invalid size: %#x\n", pkt.size);
}
}
if (pkt.size == 1)
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)
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
- offset, pkt.size, *data16);
+ offset, pkt.size, pkt.get<uint16_t>());
else
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;
return pioDelay;
IdeRegType reg_type;
int disk;
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);
if (!io_enabled) {
pkt.result = Success;
+ DPRINTF(IdeCtrl, "io not enabled\n");
return pioDelay;
}
disk = getDisk(channel);
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 (oldVal & SSBM) {
panic("Invalid BMIS write size: %x\n", pkt.size);
oldVal = bmi_regs.chan[channel].bmis;
- newVal = data8;
+ newVal = pkt.get<uint8_t>();
// the BMIDEA bit is RO
newVal |= (oldVal & BMIDEA);
if (pkt.size != sizeof(uint32_t))
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;
pkt.size);
// 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;
case COMMAND_BLOCK:
if (offset == IDE_SELECT_OFFSET) {
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!
case CONTROL_BLOCK:
case DATA_OFFSET:
switch (pkt.size) {
case sizeof(uint16_t):
- disks[disk]->write(offset, reg_type, pkt.data);
+ disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>());
break;
case sizeof(uint32_t):
- disks[disk]->write(offset, reg_type, pkt.data);
- 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.getPtr<uint8_t>() +
sizeof(uint16_t));
break;
default:
break;
default:
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
panic("IDE write of command reg of invalid size: %#x\n", pkt.size);
}
if (pkt.size == 1)
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)
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
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;
UNSERIALIZE_SCALAR(bm_enabled);
UNSERIALIZE_ARRAY(cmd_in_progress,
sizeof(cmd_in_progress) / sizeof(cmd_in_progress[0]));
+ pioPort->sendStatusChange(Port::RangeChange);
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include "dev/ide_ctrl.hh"
#include "dev/tsunami.hh"
#include "dev/tsunami_pchip.hh"
-#include "mem/packet.hh"
#include "sim/builder.hh"
#include "sim/sim_object.hh"
#include "sim/root.hh"
default:
panic("Unknown register block!\n");
}
+ DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset,
+ (uint32_t)*data);
if (action != ACT_NONE)
updateState(action);
panic("Unknown register block!\n");
}
+ DPRINTF(IdeDisk, "Write to disk at offset: %#x data %#x\n", offset,
+ (uint32_t)*data);
if (action != ACT_NONE)
updateState(action);
}
pkt->req->setPaddr(pkt->addr);
pkt->req->setSize(pkt->size);
// Increment the data pointer on a write
- pkt->data = data ? data + prevSize : NULL ;
+ if (data)
+ pkt->dataStatic(data + prevSize) ;
prevSize += pkt->size;
// Set the last bit of the dma as the final packet for this dma
// and set it's completion event.
}
assert(pendingCount >= 0);
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
-DmaPort::sendDma(Packet &pkt)
+DmaPort::sendDma(Packet *pkt)
{
// some kind of selction between access methods
// more work is going to have to be done to make
if (sendTiming(pkt) == Failure)
transmitList.push_back(&packet);
} else if (state == Atomic) {*/
- sendAtomic(pkt);
- if (pkt.senderState) {
- DmaReqState *state = (DmaReqState*)pkt.senderState;
- state->completionEvent->schedule(curTick + (pkt.time - pkt.req->getTime()) +1);
+ sendAtomic(*pkt);
+ if (pkt->senderState) {
+ DmaReqState *state = (DmaReqState*)pkt->senderState;
+ state->completionEvent->schedule(curTick + (pkt->time - pkt->req->getTime()) +1);
}
- pendingCount--;
- assert(pendingCount >= 0);
+ pendingCount--;
+ assert(pendingCount >= 0);
+ delete pkt->req;
+ delete pkt;
+
/* } else if (state == Functional) {
sendFunctional(pkt);
// Is this correct???
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) {
- case sizeof(uint64_t):
- if (!pkt.data) {
- data64 = new uint64_t;
- pkt.data = (uint8_t*)data64;
- } else {
- data64 = (uint64_t*)pkt.data;
- }
- *data64 = 0xFFFFFFFFFFFFFFFFULL;
+ pkt.set(0xFFFFFFFFFFFFFFFFULL);
break;
case sizeof(uint32_t):
- if (!pkt.data) {
- data32 = new uint32_t;
- pkt.data = (uint8_t*)data32;
- } else {
- data32 = (uint32_t*)pkt.data;
- }
- *data32 = 0xFFFFFFFF;
+ pkt.set((uint32_t)0xFFFFFFFF);
break;
case sizeof(uint16_t):
- if (!pkt.data) {
- data16 = new uint16_t;
- pkt.data = (uint8_t*)data16;
- } else {
- data16 = (uint16_t*)pkt.data;
- }
- *data16 = 0xFFFF;
+ pkt.set((uint16_t)0xFFFF);
break;
case sizeof(uint8_t):
- if (!pkt.data) {
- data8 = new uint8_t;
- pkt.data = data8;
- } else {
- data8 = (uint8_t*)pkt.data;
- }
- *data8 = 0xFF;
+ pkt.set((uint8_t)0xFF);
break;
default:
panic("invalid access size(?) for PCI configspace!\n");
#include "dev/etherlink.hh"
#include "dev/ns_gige.hh"
#include "dev/pciconfigall.hh"
-#include "mem/bus/bus.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 "mem/packet.hh"
#include "sim/builder.hh"
#include "sim/debug.hh"
#include "sim/host.hh"
#include "sim/stats.hh"
-#include "arch/vtophys.hh"
+#include "sim/system.hh"
const char *NsRxStateStrings[] =
{
txEvent(this), rxFilterEnable(p->rx_filter), acceptBroadcast(false),
acceptMulticast(false), acceptUnicast(false),
acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
- physmem(p->pmem), intrTick(0), cpuPendingIntr(false),
+ intrTick(0), cpuPendingIntr(false),
intrEvent(0), interface(0)
{
- if (p->pio_bus) {
- pioInterface = newPioInterface(name() + ".pio", p->hier,
- p->pio_bus, this,
- &NSGigE::cacheAccess);
- pioLatency = p->pio_latency * p->pio_bus->clockRate;
- }
-
- if (p->header_bus) {
- if (p->payload_bus)
- dmaInterface = new DMAInterface<Bus>(name() + ".dma",
- p->header_bus,
- p->payload_bus, 1,
- p->dma_no_allocate);
- else
- dmaInterface = new DMAInterface<Bus>(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");
intrDelay = p->intr_delay;
dmaReadDelay = p->dma_read_delay;
rxPacketRate = rxPackets / simSeconds;
}
-/**
- * This is to read the PCI general configuration registers
- */
-void
-NSGigE::readConfig(int offset, int size, uint8_t *data)
-{
- if (offset < PCI_DEVICE_SPECIFIC)
- PciDev::readConfig(offset, size, data);
- else
- panic("Device specific PCI config space not implemented!\n");
-}
/**
* This is to write to the PCI general configuration registers
*/
void
-NSGigE::writeConfig(int offset, int size, const uint8_t* data)
+NSGigE::writeConfig(int offset, const uint16_t data)
{
if (offset < PCI_DEVICE_SPECIFIC)
- PciDev::writeConfig(offset, size, data);
+ PciDev::writeConfig(offset, data);
else
panic("Device specific PCI config space not implemented!\n");
- // Need to catch writes to BARs to update the PIO interface
switch (offset) {
// seems to work fine without all these PCI settings, but i
// put in the IO to double check, an assertion will fail if we
ioEnable = true;
else
ioEnable = false;
-
-#if 0
- if (config.data[offset] & PCI_CMD_BME) {
- bmEnabled = true;
- }
- else {
- bmEnabled = false;
- }
-
- if (config.data[offset] & PCI_CMD_MSE) {
- memEnable = true;
- }
- else {
- memEnable = false;
- }
-#endif
- break;
-
- case PCI0_BASE_ADDR0:
- if (BARAddrs[0] != 0) {
- if (pioInterface)
- pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0]));
-
- BARAddrs[0] &= EV5::PAddrUncachedMask;
- }
- break;
- case PCI0_BASE_ADDR1:
- if (BARAddrs[1] != 0) {
- if (pioInterface)
- pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1]));
-
- BARAddrs[1] &= EV5::PAddrUncachedMask;
- }
break;
}
}
* This reads the device registers, which are detailed in the NS83820
* spec sheet
*/
-Fault
-NSGigE::read(MemReqPtr &req, uint8_t *data)
+Tick
+NSGigE::read(Packet &pkt)
{
assert(ioEnable);
+ pkt.time = curTick + pioDelay;
+ pkt.allocate();
+
//The mask is to give you only the offset into the device register file
- Addr daddr = req->paddr & 0xfff;
- DPRINTF(EthernetPIO, "read da=%#x pa=%#x va=%#x size=%d\n",
- daddr, req->paddr, req->vaddr, req->size);
+ Addr daddr = pkt.addr & 0xfff;
+ DPRINTF(EthernetPIO, "read da=%#x pa=%#x size=%d\n",
+ daddr, pkt.addr, pkt.size);
// there are some reserved registers, you can see ns_gige_reg.h and
if (daddr > LAST && daddr <= RESERVED) {
panic("Accessing reserved register");
} else if (daddr > RESERVED && daddr <= 0x3FC) {
- readConfig(daddr & 0xff, req->size, data);
- return NoFault;
+ if (pkt.size == sizeof(uint8_t))
+ readConfig(daddr & 0xff, pkt.getPtr<uint8_t>());
+ if (pkt.size == sizeof(uint16_t))
+ readConfig(daddr & 0xff, pkt.getPtr<uint16_t>());
+ if (pkt.size == sizeof(uint32_t))
+ readConfig(daddr & 0xff, pkt.getPtr<uint32_t>());
+ pkt.result = Success;
+ return pioDelay;
} else if (daddr >= MIB_START && daddr <= MIB_END) {
// don't implement all the MIB's. hopefully the kernel
// doesn't actually DEPEND upon their values
// MIB are just hardware stats keepers
- uint32_t ® = *(uint32_t *) data;
- reg = 0;
- return NoFault;
+ pkt.set<uint32_t>(0);
+ pkt.result = Success;
+ return pioDelay;
} else if (daddr > 0x3FC)
panic("Something is messed up!\n");
- switch (req->size) {
- case sizeof(uint32_t):
- {
- uint32_t ® = *(uint32_t *)data;
- uint16_t rfaddr;
-
- switch (daddr) {
- case CR:
- reg = regs.command;
- //these are supposed to be cleared on a read
- reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR);
- break;
+ assert(pkt.size == sizeof(uint32_t));
+ uint32_t ® = *pkt.getPtr<uint32_t>();
+ uint16_t rfaddr;
- case CFGR:
- reg = regs.config;
- break;
+ switch (daddr) {
+ case CR:
+ reg = regs.command;
+ //these are supposed to be cleared on a read
+ reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR);
+ break;
- case MEAR:
- reg = regs.mear;
- break;
+ case CFGR:
+ reg = regs.config;
+ break;
- case PTSCR:
- reg = regs.ptscr;
- break;
+ case MEAR:
+ reg = regs.mear;
+ break;
- case ISR:
- reg = regs.isr;
- devIntrClear(ISR_ALL);
- break;
+ case PTSCR:
+ reg = regs.ptscr;
+ break;
- case IMR:
- reg = regs.imr;
- break;
+ case ISR:
+ reg = regs.isr;
+ devIntrClear(ISR_ALL);
+ break;
- case IER:
- reg = regs.ier;
- break;
+ case IMR:
+ reg = regs.imr;
+ break;
- case IHR:
- reg = regs.ihr;
- break;
+ case IER:
+ reg = regs.ier;
+ break;
- case TXDP:
- reg = regs.txdp;
- break;
+ case IHR:
+ reg = regs.ihr;
+ break;
- case TXDP_HI:
- reg = regs.txdp_hi;
- break;
+ case TXDP:
+ reg = regs.txdp;
+ break;
- case TX_CFG:
- reg = regs.txcfg;
- break;
+ case TXDP_HI:
+ reg = regs.txdp_hi;
+ break;
- case GPIOR:
- reg = regs.gpior;
- break;
+ case TX_CFG:
+ reg = regs.txcfg;
+ break;
- case RXDP:
- reg = regs.rxdp;
- break;
+ case GPIOR:
+ reg = regs.gpior;
+ break;
- case RXDP_HI:
- reg = regs.rxdp_hi;
- break;
+ case RXDP:
+ reg = regs.rxdp;
+ break;
- case RX_CFG:
- reg = regs.rxcfg;
- break;
+ case RXDP_HI:
+ reg = regs.rxdp_hi;
+ break;
- case PQCR:
- reg = regs.pqcr;
- break;
+ case RX_CFG:
+ reg = regs.rxcfg;
+ break;
- case WCSR:
- reg = regs.wcsr;
- break;
+ case PQCR:
+ reg = regs.pqcr;
+ break;
- case PCR:
- reg = regs.pcr;
- break;
+ case WCSR:
+ reg = regs.wcsr;
+ break;
+
+ case PCR:
+ reg = regs.pcr;
+ break;
+
+ // see the spec sheet for how RFCR and RFDR work
+ // basically, you write to RFCR to tell the machine
+ // what you want to do next, then you act upon RFDR,
+ // and the device will be prepared b/c of what you
+ // wrote to RFCR
+ case RFCR:
+ reg = regs.rfcr;
+ break;
- // see the spec sheet for how RFCR and RFDR work
- // basically, you write to RFCR to tell the machine
- // what you want to do next, then you act upon RFDR,
- // and the device will be prepared b/c of what you
- // wrote to RFCR
- case RFCR:
- reg = regs.rfcr;
+ case RFDR:
+ rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR);
+ switch (rfaddr) {
+ // Read from perfect match ROM octets
+ case 0x000:
+ reg = rom.perfectMatch[1];
+ reg = reg << 8;
+ reg += rom.perfectMatch[0];
+ break;
+ case 0x002:
+ reg = rom.perfectMatch[3] << 8;
+ reg += rom.perfectMatch[2];
break;
+ case 0x004:
+ reg = rom.perfectMatch[5] << 8;
+ reg += rom.perfectMatch[4];
+ break;
+ default:
+ // Read filter hash table
+ if (rfaddr >= FHASH_ADDR &&
+ rfaddr < FHASH_ADDR + FHASH_SIZE) {
- case RFDR:
- rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR);
- switch (rfaddr) {
- // Read from perfect match ROM octets
- case 0x000:
- reg = rom.perfectMatch[1];
- reg = reg << 8;
- reg += rom.perfectMatch[0];
- break;
- case 0x002:
- reg = rom.perfectMatch[3] << 8;
- reg += rom.perfectMatch[2];
- break;
- case 0x004:
- reg = rom.perfectMatch[5] << 8;
- reg += rom.perfectMatch[4];
- break;
- default:
- // Read filter hash table
- if (rfaddr >= FHASH_ADDR &&
- rfaddr < FHASH_ADDR + FHASH_SIZE) {
-
- // Only word-aligned reads supported
- if (rfaddr % 2)
- panic("unaligned read from filter hash table!");
-
- reg = rom.filterHash[rfaddr - FHASH_ADDR + 1] << 8;
- reg += rom.filterHash[rfaddr - FHASH_ADDR];
- break;
- }
+ // Only word-aligned reads supported
+ if (rfaddr % 2)
+ panic("unaligned read from filter hash table!");
- panic("reading RFDR for something other than pattern"
- " matching or hashing! %#x\n", rfaddr);
+ reg = rom.filterHash[rfaddr - FHASH_ADDR + 1] << 8;
+ reg += rom.filterHash[rfaddr - FHASH_ADDR];
+ break;
}
- break;
- case SRR:
- reg = regs.srr;
- break;
+ panic("reading RFDR for something other than pattern"
+ " matching or hashing! %#x\n", rfaddr);
+ }
+ break;
- case MIBC:
- reg = regs.mibc;
- reg &= ~(MIBC_MIBS | MIBC_ACLR);
- break;
+ case SRR:
+ reg = regs.srr;
+ break;
- case VRCR:
- reg = regs.vrcr;
- break;
+ case MIBC:
+ reg = regs.mibc;
+ reg &= ~(MIBC_MIBS | MIBC_ACLR);
+ break;
- case VTCR:
- reg = regs.vtcr;
- break;
+ case VRCR:
+ reg = regs.vrcr;
+ break;
- case VDR:
- reg = regs.vdr;
- break;
+ case VTCR:
+ reg = regs.vtcr;
+ break;
- case CCSR:
- reg = regs.ccsr;
- break;
+ case VDR:
+ reg = regs.vdr;
+ break;
- case TBICR:
- reg = regs.tbicr;
- break;
+ case CCSR:
+ reg = regs.ccsr;
+ break;
- case TBISR:
- reg = regs.tbisr;
- break;
+ case TBICR:
+ reg = regs.tbicr;
+ break;
- case TANAR:
- reg = regs.tanar;
- break;
+ case TBISR:
+ reg = regs.tbisr;
+ break;
- case TANLPAR:
- reg = regs.tanlpar;
- break;
+ case TANAR:
+ reg = regs.tanar;
+ break;
- case TANER:
- reg = regs.taner;
- break;
+ case TANLPAR:
+ reg = regs.tanlpar;
+ break;
- case TESR:
- reg = regs.tesr;
- break;
+ case TANER:
+ reg = regs.taner;
+ break;
- case M5REG:
- reg = 0;
- if (params()->rx_thread)
- reg |= M5REG_RX_THREAD;
- if (params()->tx_thread)
- reg |= M5REG_TX_THREAD;
- if (params()->rss)
- reg |= M5REG_RSS;
- break;
+ case TESR:
+ reg = regs.tesr;
+ break;
- default:
- panic("reading unimplemented register: addr=%#x", daddr);
- }
+ case M5REG:
+ reg = 0;
+ if (params()->rx_thread)
+ reg |= M5REG_RX_THREAD;
+ if (params()->tx_thread)
+ reg |= M5REG_TX_THREAD;
+ if (params()->rss)
+ reg |= M5REG_RSS;
+ break;
- DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n",
- daddr, reg, reg);
+ default:
+ panic("reading unimplemented register: addr=%#x", daddr);
}
- break;
- default:
- panic("accessing register with invalid size: addr=%#x, size=%d",
- daddr, req->size);
- }
+ DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n",
+ daddr, reg, reg);
- return NoFault;
+ pkt.result = Success;
+ return pioDelay;
}
-Fault
-NSGigE::write(MemReqPtr &req, const uint8_t *data)
+Tick
+NSGigE::write(Packet &pkt)
{
assert(ioEnable);
- Addr daddr = req->paddr & 0xfff;
- DPRINTF(EthernetPIO, "write da=%#x pa=%#x va=%#x size=%d\n",
- daddr, req->paddr, req->vaddr, req->size);
+ Addr daddr = pkt.addr & 0xfff;
+ DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n",
+ daddr, pkt.addr, pkt.size);
+
+ pkt.time = curTick + pioDelay;
if (daddr > LAST && daddr <= RESERVED) {
panic("Accessing reserved register");
} else if (daddr > RESERVED && daddr <= 0x3FC) {
- writeConfig(daddr & 0xff, req->size, data);
- return NoFault;
+ if (pkt.size == sizeof(uint8_t))
+ writeConfig(daddr & 0xff, pkt.get<uint8_t>());
+ if (pkt.size == sizeof(uint16_t))
+ writeConfig(daddr & 0xff, pkt.get<uint16_t>());
+ if (pkt.size == sizeof(uint32_t))
+ writeConfig(daddr & 0xff, pkt.get<uint32_t>());
+ pkt.result = Success;
+ return pioDelay;
} else if (daddr > 0x3FC)
panic("Something is messed up!\n");
- if (req->size == sizeof(uint32_t)) {
- uint32_t reg = *(uint32_t *)data;
+ if (pkt.size == sizeof(uint32_t)) {
+ uint32_t reg = pkt.get<uint32_t>();
uint16_t rfaddr;
DPRINTF(EthernetPIO, "write data=%d data=%#x\n", reg, reg);
} else {
panic("Invalid Request Size");
}
-
- return NoFault;
+ pkt.result = Success;
+ return pioDelay;
}
void
acceptArp = false;
}
-void
-NSGigE::rxDmaReadCopy()
-{
- assert(rxDmaState == dmaReading);
-
- physmem->dma_read((uint8_t *)rxDmaData, rxDmaAddr, rxDmaLen);
- rxDmaState = dmaIdle;
-
- DPRINTF(EthernetDMA, "rx dma read paddr=%#x len=%d\n",
- rxDmaAddr, rxDmaLen);
- DDUMP(EthernetDMA, rxDmaData, rxDmaLen);
-}
-
bool
NSGigE::doRxDmaRead()
{
assert(rxDmaState == dmaIdle || rxDmaState == dmaReadWaiting);
rxDmaState = dmaReading;
- if (dmaInterface && !rxDmaFree) {
- if (dmaInterface->busy())
- rxDmaState = dmaReadWaiting;
- else
- dmaInterface->doDMA(Read, rxDmaAddr, rxDmaLen, curTick,
- &rxDmaReadEvent, true);
- return true;
- }
-
- if (dmaReadDelay == 0 && dmaReadFactor == 0) {
- rxDmaReadCopy();
- return false;
- }
+ if (dmaPending())
+ rxDmaState = dmaReadWaiting;
+ else
+ dmaRead(rxDmaAddr, rxDmaLen, &rxDmaReadEvent, (uint8_t*)rxDmaData);
- Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor;
- Tick start = curTick + dmaReadDelay + factor;
- rxDmaReadEvent.schedule(start);
return true;
}
NSGigE::rxDmaReadDone()
{
assert(rxDmaState == dmaReading);
- rxDmaReadCopy();
+ rxDmaState = dmaIdle;
+
+ DPRINTF(EthernetDMA, "rx dma read paddr=%#x len=%d\n",
+ rxDmaAddr, rxDmaLen);
+ DDUMP(EthernetDMA, rxDmaData, rxDmaLen);
// If the transmit state machine has a pending DMA, let it go first
if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting)
rxKick();
}
-void
-NSGigE::rxDmaWriteCopy()
-{
- assert(rxDmaState == dmaWriting);
-
- physmem->dma_write(rxDmaAddr, (uint8_t *)rxDmaData, rxDmaLen);
- rxDmaState = dmaIdle;
-
- DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n",
- rxDmaAddr, rxDmaLen);
- DDUMP(EthernetDMA, rxDmaData, rxDmaLen);
-}
-
bool
NSGigE::doRxDmaWrite()
{
assert(rxDmaState == dmaIdle || rxDmaState == dmaWriteWaiting);
rxDmaState = dmaWriting;
- if (dmaInterface && !rxDmaFree) {
- if (dmaInterface->busy())
- rxDmaState = dmaWriteWaiting;
- else
- dmaInterface->doDMA(WriteInvalidate, rxDmaAddr, rxDmaLen, curTick,
- &rxDmaWriteEvent, true);
- return true;
- }
-
- if (dmaWriteDelay == 0 && dmaWriteFactor == 0) {
- rxDmaWriteCopy();
- return false;
- }
-
- Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor;
- Tick start = curTick + dmaWriteDelay + factor;
- rxDmaWriteEvent.schedule(start);
+ if (dmaPending())
+ rxDmaState = dmaWriteWaiting;
+ else
+ dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaWriteEvent, (uint8_t*)rxDmaData);
return true;
}
NSGigE::rxDmaWriteDone()
{
assert(rxDmaState == dmaWriting);
- rxDmaWriteCopy();
+ rxDmaState = dmaIdle;
+
+ DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n",
+ rxDmaAddr, rxDmaLen);
+ DDUMP(EthernetDMA, rxDmaData, rxDmaLen);
// If the transmit state machine has a pending DMA, let it go first
if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting)
}
}
-void
-NSGigE::txDmaReadCopy()
-{
- assert(txDmaState == dmaReading);
-
- physmem->dma_read((uint8_t *)txDmaData, txDmaAddr, txDmaLen);
- txDmaState = dmaIdle;
-
- DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n",
- txDmaAddr, txDmaLen);
- DDUMP(EthernetDMA, txDmaData, txDmaLen);
-}
-
bool
NSGigE::doTxDmaRead()
{
assert(txDmaState == dmaIdle || txDmaState == dmaReadWaiting);
txDmaState = dmaReading;
- if (dmaInterface && !txDmaFree) {
- if (dmaInterface->busy())
- txDmaState = dmaReadWaiting;
- else
- dmaInterface->doDMA(Read, txDmaAddr, txDmaLen, curTick,
- &txDmaReadEvent, true);
- return true;
- }
-
- if (dmaReadDelay == 0 && dmaReadFactor == 0.0) {
- txDmaReadCopy();
- return false;
- }
+ if (dmaPending())
+ txDmaState = dmaReadWaiting;
+ else
+ dmaRead(txDmaAddr, txDmaLen, &txDmaReadEvent, (uint8_t*)txDmaData);
- Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor;
- Tick start = curTick + dmaReadDelay + factor;
- txDmaReadEvent.schedule(start);
return true;
}
NSGigE::txDmaReadDone()
{
assert(txDmaState == dmaReading);
- txDmaReadCopy();
+ txDmaState = dmaIdle;
+
+ DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n",
+ txDmaAddr, txDmaLen);
+ DDUMP(EthernetDMA, txDmaData, txDmaLen);
// If the receive state machine has a pending DMA, let it go first
if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting)
txKick();
}
-void
-NSGigE::txDmaWriteCopy()
-{
- assert(txDmaState == dmaWriting);
-
- physmem->dma_write(txDmaAddr, (uint8_t *)txDmaData, txDmaLen);
- txDmaState = dmaIdle;
-
- DPRINTF(EthernetDMA, "tx dma write paddr=%#x len=%d\n",
- txDmaAddr, txDmaLen);
- DDUMP(EthernetDMA, txDmaData, txDmaLen);
-}
-
bool
NSGigE::doTxDmaWrite()
{
assert(txDmaState == dmaIdle || txDmaState == dmaWriteWaiting);
txDmaState = dmaWriting;
- if (dmaInterface && !txDmaFree) {
- if (dmaInterface->busy())
- txDmaState = dmaWriteWaiting;
- else
- dmaInterface->doDMA(WriteInvalidate, txDmaAddr, txDmaLen, curTick,
- &txDmaWriteEvent, true);
- return true;
- }
-
- if (dmaWriteDelay == 0 && dmaWriteFactor == 0.0) {
- txDmaWriteCopy();
- return false;
- }
-
- Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor;
- Tick start = curTick + dmaWriteDelay + factor;
- txDmaWriteEvent.schedule(start);
+ if (dmaPending())
+ txDmaState = dmaWriteWaiting;
+ else
+ dmaWrite(txDmaAddr, txDmaLen, &txDmaWriteEvent, (uint8_t*)txDmaData);
return true;
}
NSGigE::txDmaWriteDone()
{
assert(txDmaState == dmaWriting);
- txDmaWriteCopy();
+ txDmaState = dmaIdle;
+
+ DPRINTF(EthernetDMA, "tx dma write paddr=%#x len=%d\n",
+ txDmaAddr, txDmaLen);
+ DDUMP(EthernetDMA, txDmaData, txDmaLen);
// If the receive state machine has a pending DMA, let it go first
if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting)
case txFifoBlock:
if (!txPacket) {
DPRINTF(EthernetSM, "****starting the tx of a new packet****\n");
- txPacket = new PacketData(16384);
+ txPacket = new EthPacketData(16384);
txPacketBufPtr = txPacket->data;
}
}
bool
-NSGigE::rxFilter(const PacketPtr &packet)
+NSGigE::rxFilter(const EthPacketPtr &packet)
{
EthPtr eth = packet;
bool drop = true;
}
bool
-NSGigE::recvPacket(PacketPtr packet)
+NSGigE::recvPacket(EthPacketPtr packet)
{
rxBytes += packet->length;
rxPackets++;
/*
* Finalize any DMA events now.
*/
- if (rxDmaReadEvent.scheduled())
- rxDmaReadCopy();
- if (rxDmaWriteEvent.scheduled())
- rxDmaWriteCopy();
- if (txDmaReadEvent.scheduled())
- txDmaReadCopy();
- if (txDmaWriteEvent.scheduled())
- txDmaWriteCopy();
+ // @todo will mem system save pending dma?
/*
* Serialize the device registers
bool txPacketExists;
UNSERIALIZE_SCALAR(txPacketExists);
if (txPacketExists) {
- txPacket = new PacketData(16384);
+ txPacket = new EthPacketData(16384);
txPacket->unserialize("txPacket", cp, section);
uint32_t txPktBufPtr;
UNSERIALIZE_SCALAR(txPktBufPtr);
UNSERIALIZE_SCALAR(rxPacketExists);
rxPacket = 0;
if (rxPacketExists) {
- rxPacket = new PacketData(16384);
+ rxPacket = new EthPacketData(16384);
rxPacket->unserialize("rxPacket", cp, section);
uint32_t rxPktBufPtr;
UNSERIALIZE_SCALAR(rxPktBufPtr);
intrEvent = new IntrEvent(this, true);
intrEvent->schedule(intrEventTick);
}
-
- /*
- * re-add addrRanges to bus bridges
- */
- if (pioInterface) {
- pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0]));
- pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1]));
- }
-}
-
-Tick
-NSGigE::cacheAccess(MemReqPtr &req)
-{
- DPRINTF(EthernetPIO, "timing access to paddr=%#x (daddr=%#x)\n",
- req->paddr, req->paddr & 0xfff);
-
- return curTick + pioLatency;
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt)
BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
- Param<Tick> clock;
-
- Param<Addr> addr;
- SimObjectParam<MemoryController *> mmu;
- SimObjectParam<PhysicalMemory *> physmem;
+ SimObjectParam<System *> system;
+ SimObjectParam<Platform *> platform;
SimObjectParam<PciConfigAll *> configspace;
SimObjectParam<PciConfigData *> configdata;
- SimObjectParam<Platform *> platform;
Param<uint32_t> pci_bus;
Param<uint32_t> pci_dev;
Param<uint32_t> pci_func;
+ Param<Tick> pio_latency;
- SimObjectParam<HierParams *> hier;
- SimObjectParam<Bus*> pio_bus;
- SimObjectParam<Bus*> dma_bus;
- SimObjectParam<Bus*> payload_bus;
+ Param<Tick> clock;
Param<bool> dma_desc_free;
Param<bool> dma_data_free;
Param<Tick> dma_read_delay;
Param<Tick> dma_read_factor;
Param<Tick> dma_write_factor;
Param<bool> dma_no_allocate;
- Param<Tick> pio_latency;
Param<Tick> intr_delay;
Param<Tick> rx_delay;
BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
- INIT_PARAM(clock, "State machine processor frequency"),
-
- INIT_PARAM(addr, "Device Address"),
- INIT_PARAM(mmu, "Memory Controller"),
- INIT_PARAM(physmem, "Physical Memory"),
+ INIT_PARAM(system, "System pointer"),
+ INIT_PARAM(platform, "Platform pointer"),
INIT_PARAM(configspace, "PCI Configspace"),
INIT_PARAM(configdata, "PCI Config data"),
- INIT_PARAM(platform, "Platform"),
- INIT_PARAM(pci_bus, "PCI bus"),
+ INIT_PARAM(pci_bus, "PCI bus ID"),
INIT_PARAM(pci_dev, "PCI device number"),
INIT_PARAM(pci_func, "PCI function code"),
+ INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
+ 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_desc_free, "DMA of Descriptors is free"),
INIT_PARAM(dma_data_free, "DMA of Data is free"),
INIT_PARAM(dma_read_delay, "fixed delay for dma reads"),
INIT_PARAM(dma_read_factor, "multiplier for dma reads"),
INIT_PARAM(dma_write_factor, "multiplier for dma writes"),
INIT_PARAM(dma_no_allocate, "Should DMA reads allocate cache lines"),
- INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"),
INIT_PARAM(intr_delay, "Interrupt Delay in microseconds"),
INIT_PARAM(rx_delay, "Receive Delay"),
NSGigE::Params *params = new NSGigE::Params;
params->name = getInstanceName();
-
- params->clock = clock;
-
- params->mmu = mmu;
- params->pmem = physmem;
+ params->platform = platform;
+ params->system = system;
params->configSpace = configspace;
params->configData = configdata;
- params->plat = platform;
params->busNum = pci_bus;
params->deviceNum = pci_dev;
params->functionNum = pci_func;
+ params->pio_delay = pio_latency;
- params->hier = hier;
- params->pio_bus = pio_bus;
- params->header_bus = dma_bus;
- params->payload_bus = payload_bus;
+ params->clock = clock;
params->dma_desc_free = dma_desc_free;
params->dma_data_free = dma_data_free;
params->dma_read_delay = dma_read_delay;
params->dma_read_factor = dma_read_factor;
params->dma_write_factor = dma_write_factor;
params->dma_no_allocate = dma_no_allocate;
- params->pio_latency = pio_latency;
+ params->pio_delay = pio_latency;
params->intr_delay = intr_delay;
params->rx_delay = rx_delay;
#include "dev/ns_gige_reg.h"
#include "dev/pcidev.hh"
#include "dev/pktfifo.hh"
-#include "mem/bus/bus.hh"
#include "sim/eventq.hh"
// Hash filtering constants
};
class NSGigEInt;
-class PhysicalMemory;
-class BaseInterface;
-class HierParams;
-class Bus;
+class Packet;
class PciConfigAll;
/**
eepromRead
};
- private:
- Addr addr;
- static const Addr size = sizeof(dp_regs);
-
protected:
/** device register file */
dp_regs regs;
PacketFifo rxFifo;
/** various helper vars */
- PacketPtr txPacket;
- PacketPtr rxPacket;
+ EthPacketPtr txPacket;
+ EthPacketPtr rxPacket;
uint8_t *txPacketBufPtr;
uint8_t *rxPacketBufPtr;
uint32_t txXferLen;
int rxDmaLen;
bool doRxDmaRead();
bool doRxDmaWrite();
- void rxDmaReadCopy();
- void rxDmaWriteCopy();
void *txDmaData;
Addr txDmaAddr;
int txDmaLen;
bool doTxDmaRead();
bool doTxDmaWrite();
- void txDmaReadCopy();
- void txDmaWriteCopy();
void rxDmaReadDone();
friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
* receive address filter
*/
bool rxFilterEnable;
- bool rxFilter(const PacketPtr &packet);
+ bool rxFilter(const EthPacketPtr &packet);
bool acceptBroadcast;
bool acceptMulticast;
bool acceptUnicast;
bool acceptArp;
bool multicastHashEnable;
- PhysicalMemory *physmem;
-
/**
* Interrupt management
*/
public:
struct Params : public PciDev::Params
{
- PhysicalMemory *pmem;
- HierParams *hier;
- Bus *pio_bus;
- Bus *header_bus;
- Bus *payload_bus;
Tick clock;
Tick intr_delay;
Tick tx_delay;
Tick rx_delay;
- Tick pio_latency;
bool dma_desc_free;
bool dma_data_free;
Tick dma_read_delay;
~NSGigE();
const Params *params() const { return (const Params *)_params; }
- virtual void writeConfig(int offset, int size, const uint8_t *data);
- virtual void readConfig(int offset, int size, uint8_t *data);
+ virtual void writeConfig(int offset, const uint16_t data);
- virtual Fault read(MemReqPtr &req, uint8_t *data);
- virtual Fault write(MemReqPtr &req, const uint8_t *data);
+ virtual Tick read(Packet &pkt);
+ virtual Tick write(Packet &pkt);
bool cpuIntrPending() const;
void cpuIntrAck() { cpuIntrClear(); }
- bool recvPacket(PacketPtr packet);
+ bool recvPacket(EthPacketPtr packet);
void transferDone();
void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
Stats::Formula coalescedTotal;
Stats::Scalar<> postedInterrupts;
Stats::Scalar<> droppedPackets;
-
- public:
- Tick cacheAccess(MemReqPtr &req);
};
/*
NSGigEInt(const std::string &name, NSGigE *d)
: 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(); }
};
int reg = daddr & 0xFF;
pkt.time = curTick + pioDelay;
+ pkt.allocate();
DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt.addr, daddr,
pkt.size);
- uint8_t *data8;
- uint16_t *data16;
- uint32_t *data32;
-
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):
- if (!pkt.data) {
- data32 = new uint32_t;
- pkt.data = (uint8_t*)data32;
- } else {
- data32 = (uint32_t*)pkt.data;
- }
if (devices[device][func] == NULL)
- *data32 = 0xFFFFFFFF;
+ pkt.set<uint32_t>(0xFFFFFFFF);
else
- devices[device][func]->readConfig(reg, data32);
+ devices[device][func]->readConfig(reg, pkt.getPtr<uint32_t>());
break;
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)
- *data16 = 0xFFFF;
+ pkt.set<uint16_t>(0xFFFF);
else
- devices[device][func]->readConfig(reg, data16);
+ devices[device][func]->readConfig(reg, pkt.getPtr<uint16_t>());
break;
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)
- *data8 = 0xFF;
+ pkt.set<uint8_t>(0xFF);
else
- devices[device][func]->readConfig(reg, data8);
+ devices[device][func]->readConfig(reg, pkt.getPtr<uint8_t>());
break;
default:
panic("invalid access size(?) for PCI configspace!\n");
panic("Attempting to write to config space on non-existant device\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) {
case sizeof(uint8_t):
- devices[device][func]->writeConfig(reg, *pkt.data);
+ devices[device][func]->writeConfig(reg, pkt.get<uint8_t>());
break;
case sizeof(uint16_t):
- devices[device][func]->writeConfig(reg, *(uint16_t*)pkt.data);
+ devices[device][func]->writeConfig(reg, pkt.get<uint16_t>());
break;
case sizeof(uint32_t):
- devices[device][func]->writeConfig(reg, *(uint32_t*)pkt.data);
+ devices[device][func]->writeConfig(reg, pkt.get<uint32_t>());
break;
default:
panic("invalid pci config write size\n");
if (offset + len >= size())
return false;
- list<PacketPtr>::iterator p = fifo.begin();
- list<PacketPtr>::iterator end = fifo.end();
+ list<EthPacketPtr>::iterator p = fifo.begin();
+ list<EthPacketPtr>::iterator end = fifo.end();
while (len > 0) {
while (offset >= (*p)->length) {
offset -= (*p)->length;
paramOut(os, base + ".packets", fifo.size());
int i = 0;
- list<PacketPtr>::iterator p = fifo.begin();
- list<PacketPtr>::iterator end = fifo.end();
+ list<EthPacketPtr>::iterator p = fifo.begin();
+ list<EthPacketPtr>::iterator end = fifo.end();
while (p != end) {
(*p)->serialize(csprintf("%s.packet%d", base, i), os);
++p;
fifo.clear();
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);
fifo.push_back(p);
}
class PacketFifo
{
public:
- typedef std::list<PacketPtr> fifo_list;
+ typedef std::list<EthPacketPtr> fifo_list;
typedef fifo_list::iterator iterator;
protected:
- std::list<PacketPtr> fifo;
+ std::list<EthPacketPtr> fifo;
int _maxsize;
int _size;
int _reserved;
iterator begin() { return fifo.begin(); }
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(_reserved <= ptr->length);
if (empty())
return;
- PacketPtr &packet = fifo.front();
+ EthPacketPtr &packet = fifo.front();
_size -= packet->length;
_size -= packet->slack;
packet->slack = 0;
void remove(iterator i)
{
- PacketPtr &packet = *i;
+ EthPacketPtr &packet = *i;
if (i != fifo.begin()) {
iterator prev = i;
--prev;
#include <cstdio>
#include <deque>
+#include <limits>
#include <string>
#include "base/inet.hh"
#include "dev/etherlink.hh"
#include "dev/sinic.hh"
#include "dev/pciconfigall.hh"
-#include "mem/bus/bus.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 "mem/packet.hh"
#include "sim/builder.hh"
#include "sim/debug.hh"
#include "sim/eventq.hh"
}
Device::Device(Params *p)
- : Base(p), plat(p->plat), physmem(p->physmem),
- rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size),
+ : Base(p), rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size),
rxKickTick(0), txKickTick(0),
txEvent(this), rxDmaEvent(this), txDmaEvent(this),
dmaReadDelay(p->dma_read_delay), dmaReadFactor(p->dma_read_factor),
{
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()
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
Device::prepareIO(int cpu, int index)
{
/**
* I/O read of device register
*/
-Fault
-Device::read(MemReqPtr &req, uint8_t *data)
+Tick
+Device::read(Packet &pkt)
{
assert(config.command & PCI_CMD_MSE);
- Fault fault = readBar(req, data);
-
- if (fault->isMachineCheckFault()) {
- panic("address does not map to a BAR pa=%#x va=%#x size=%d",
- req->paddr, req->vaddr, req->size);
-
- return genMachineCheckFault();
- }
+ assert(pkt.addr >= BARAddrs[0] && pkt.size < BARSize[0]);
- return fault;
-}
-
-Fault
-Device::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data)
-{
- int cpu = (req->xc->readMiscReg(TheISA::IPR_PALtemp16) >> 8) & 0xff;
+ int cpu = pkt.req->getCpuNum();
+ Addr daddr = pkt.addr - BARAddrs[0];
Addr index = daddr >> Regs::VirtualShift;
Addr raddr = daddr & Regs::VirtualMask;
+ pkt.time = curTick + pioDelay;
+ pkt.allocate();
+
if (!regValid(raddr))
- panic("invalid register: cpu=%d, da=%#x pa=%#x va=%#x size=%d",
- cpu, daddr, req->paddr, req->vaddr, req->size);
+ panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d",
+ cpu, daddr, pkt.addr, pkt.size);
const Regs::Info &info = regInfo(raddr);
if (!info.read)
- panic("reading %s (write only): cpu=%d da=%#x pa=%#x va=%#x size=%d",
- info.name, cpu, daddr, req->paddr, req->vaddr, req->size);
+ panic("reading %s (write only): cpu=%d da=%#x pa=%#x size=%d",
+ info.name, cpu, daddr, pkt.addr, pkt.size);
- if (req->size != info.size)
- panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x va=%#x size=%d",
- info.name, cpu, daddr, req->paddr, req->vaddr, req->size);
+ if (pkt.size != info.size)
+ panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x size=%d",
+ info.name, cpu, daddr, pkt.addr, pkt.size);
prepareRead(cpu, index);
uint64_t value = 0;
- if (req->size == 4) {
- uint32_t ® = *(uint32_t *)data;
- reg = regData32(raddr);
+ if (pkt.size == 4) {
+ uint32_t reg = regData32(raddr);
+ pkt.set(reg);
value = reg;
}
- if (req->size == 8) {
- uint64_t ® = *(uint64_t *)data;
- reg = regData64(raddr);
+ if (pkt.size == 8) {
+ uint64_t reg = regData64(raddr);
+ pkt.set(reg);
value = reg;
}
DPRINTF(EthernetPIO,
- "read %s cpu=%d da=%#x pa=%#x va=%#x size=%d val=%#x\n",
- info.name, cpu, daddr, req->paddr, req->vaddr, req->size, value);
+ "read %s cpu=%d da=%#x pa=%#x size=%d val=%#x\n",
+ info.name, cpu, daddr, pkt.addr, pkt.size, value);
// reading the interrupt status register has the side effect of
// clearing it
if (raddr == Regs::IntrStatus)
devIntrClear();
- return NoFault;
+ return pioDelay;
}
/**
* IPR read of device register
- */
-Fault
+
+ Fault
Device::iprRead(Addr daddr, int cpu, uint64_t &result)
{
if (!regValid(daddr))
return NoFault;
}
-
+*/
/**
* I/O write of device register
*/
-Fault
-Device::write(MemReqPtr &req, const uint8_t *data)
+Tick
+Device::write(Packet &pkt)
{
assert(config.command & PCI_CMD_MSE);
- Fault fault = writeBar(req, data);
-
- if (fault->isMachineCheckFault()) {
- panic("address does not map to a BAR pa=%#x va=%#x size=%d",
- req->paddr, req->vaddr, req->size);
+ assert(pkt.addr >= BARAddrs[0] && pkt.size < BARSize[0]);
- 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;
+ int cpu = pkt.req->getCpuNum();
+ Addr daddr = pkt.addr - BARAddrs[0];
Addr index = daddr >> Regs::VirtualShift;
Addr raddr = daddr & Regs::VirtualMask;
+ pkt.time = curTick + pioDelay;
+
if (!regValid(raddr))
- panic("invalid address: cpu=%d da=%#x pa=%#x va=%#x size=%d",
- cpu, daddr, req->paddr, req->vaddr, req->size);
+ panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d",
+ cpu, daddr, pkt.addr, pkt.size);
const Regs::Info &info = regInfo(raddr);
if (!info.write)
- panic("writing %s (read only): cpu=%d da=%#x",
- info.name, cpu, daddr);
+ panic("write %s (read only): cpu=%d da=%#x pa=%#x size=%d",
+ info.name, cpu, daddr, pkt.addr, pkt.size);
- if (req->size != info.size)
- panic("invalid size for %s: cpu=%d da=%#x pa=%#x va=%#x size=%d",
- info.name, cpu, daddr, req->paddr, req->vaddr, req->size);
+ if (pkt.size != info.size)
+ panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x size=%d",
+ info.name, cpu, daddr, pkt.addr, pkt.size);
- uint32_t reg32 = *(uint32_t *)data;
- uint64_t reg64 = *(uint64_t *)data;
VirtualReg &vnic = virtualRegs[index];
DPRINTF(EthernetPIO,
- "write %s: cpu=%d val=%#x da=%#x pa=%#x va=%#x size=%d\n",
- info.name, cpu, info.size == 4 ? reg32 : reg64,
- daddr, req->paddr, req->vaddr, req->size);
+ "write %s: cpu=%d val=%#x da=%#x pa=%#x size=%d\n",
+ info.name, cpu, info.size == 4 ? pkt.get<uint32_t>() :
+ pkt.get<uint64_t>(), daddr, pkt.addr, pkt.size);
prepareWrite(cpu, index);
switch (raddr) {
case Regs::Config:
- changeConfig(reg32);
+ changeConfig(pkt.get<uint32_t>());
break;
case Regs::Command:
- command(reg32);
+ command(pkt.get<uint32_t>());
break;
case Regs::IntrStatus:
- devIntrClear(regs.IntrStatus & reg32);
+ devIntrClear(regs.IntrStatus & pkt.get<uint32_t>());
break;
case Regs::IntrMask:
- devIntrChangeMask(reg32);
+ devIntrChangeMask(pkt.get<uint32_t>());
break;
case Regs::RxData:
RxStateStrings[rxState]);
vnic.RxDone = Regs::RxDone_Busy;
- vnic.RxData = reg64;
+ vnic.RxData = pkt.get<uint64_t>();
rxList.push_back(index);
if (rxEnable && rxState == rxIdle) {
rxState = rxFifoBlock;
TxStateStrings[txState]);
vnic.TxDone = Regs::TxDone_Busy;
- vnic.TxData = reg64;
+ vnic.TxData = pkt.get<uint64_t>();
if (txList.empty() || txList.front() != index)
txList.push_back(index);
if (txEnable && txState == txIdle && txList.front() == index) {
break;
}
- return NoFault;
+ return pioDelay;
}
void
}
void
-Device::rxDmaCopy()
+Device::rxDmaDone()
{
assert(rxState == rxCopy);
rxState = rxCopyDone;
- physmem->dma_write(rxDmaAddr, (uint8_t *)rxDmaData, rxDmaLen);
DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n",
rxDmaAddr, rxDmaLen);
DDUMP(EthernetData, rxDmaData, rxDmaLen);
-}
-
-void
-Device::rxDmaDone()
-{
- rxDmaCopy();
// If the transmit state machine has a pending DMA, let it go first
if (txState == txBeginCopy)
break;
case rxBeginCopy:
- if (dmaInterface && dmaInterface->busy())
+ if (dmaPending())
goto exit;
- rxDmaAddr = plat->pciToDma(Regs::get_RxData_Addr(vnic->RxData));
- rxDmaLen = min<int>(Regs::get_RxData_Len(vnic->RxData),
+ rxDmaAddr = params()->platform->pciToDma(
+ Regs::get_RxData_Addr(vnic->RxData));
+ rxDmaLen = std::min<int>(Regs::get_RxData_Len(vnic->RxData),
vnic->rxPacketBytes);
rxDmaData = (*vnic->rxPacket)->data + vnic->rxPacketOffset;
rxState = rxCopy;
- if (dmaInterface) {
- 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();
+ dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaEvent, rxDmaData);
break;
case rxCopy:
}
void
-Device::txDmaCopy()
+Device::txDmaDone()
{
assert(txState == txCopy);
txState = txCopyDone;
- physmem->dma_read((uint8_t *)txDmaData, txDmaAddr, txDmaLen);
DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n",
txDmaAddr, txDmaLen);
DDUMP(EthernetData, txDmaData, txDmaLen);
-}
-
-void
-Device::txDmaDone()
-{
- txDmaCopy();
// If the receive state machine has a pending DMA, let it go first
if (rxState == rxBeginCopy)
}
uint32_t interrupts;
- PacketPtr packet = txFifo.front();
+ EthPacketPtr packet = txFifo.front();
if (!interface->sendPacket(packet)) {
DPRINTF(Ethernet, "Packet Transmit: failed txFifo available %d\n",
txFifo.avail());
assert(Regs::get_TxDone_Busy(vnic->TxData));
if (!txPacket) {
// Grab a new packet from the fifo.
- txPacket = new PacketData(16384);
+ txPacket = new EthPacketData(16384);
txPacketOffset = 0;
}
break;
case txBeginCopy:
- if (dmaInterface && dmaInterface->busy())
+ if (dmaPending())
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);
txDmaData = txPacket->data + txPacketOffset;
txState = txCopy;
- if (dmaInterface) {
- 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();
+ dmaRead(txDmaAddr, txDmaLen, &txDmaEvent, txDmaData);
break;
case txCopy:
}
bool
-Device::rxFilter(const PacketPtr &packet)
+Device::rxFilter(const EthPacketPtr &packet)
{
if (!Regs::get_Config_Filter(regs.Config))
return false;
}
bool
-Device::recvPacket(PacketPtr packet)
+Device::recvPacket(EthPacketPtr packet)
{
rxBytes += packet->length;
rxPackets++;
//
//
void
-Base::serialize(ostream &os)
+Base::serialize(std::ostream &os)
{
// Serialize the PciDev base class
PciDev::serialize(os);
}
void
-Device::serialize(ostream &os)
+Device::serialize(std::ostream &os)
{
// Serialize the PciDev base class
Base::serialize(os);
for (int i = 0; i < virtualRegsSize; ++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 + ".RxDone", vnic->RxDone);
paramOut(os, reg + ".TxData", vnic->TxData);
UNSERIALIZE_SCALAR(txPacketExists);
txPacket = 0;
if (txPacketExists) {
- txPacket = new PacketData(16384);
+ txPacket = new EthPacketData(16384);
txPacket->unserialize("txPacket", cp, section);
UNSERIALIZE_SCALAR(txPacketOffset);
UNSERIALIZE_SCALAR(txPacketBytes);
virtualRegs.resize(virtualRegsSize);
for (int i = 0; i < virtualRegsSize; ++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 + ".RxDone", vnic->RxDone);
if (transmitTick)
txEvent.schedule(curTick + transmitTick);
- /*
- * 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);
+ pioPort->sendStatusChange(Port::RangeChange);
- 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)
SimObjectParam<EtherInt *> peer;
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
- Param<Tick> clock;
- Param<Addr> addr;
- SimObjectParam<MemoryController *> mmu;
- SimObjectParam<PhysicalMemory *> physmem;
+ SimObjectParam<System *> system;
+ SimObjectParam<Platform *> platform;
SimObjectParam<PciConfigAll *> configspace;
SimObjectParam<PciConfigData *> configdata;
- SimObjectParam<Platform *> platform;
Param<uint32_t> pci_bus;
Param<uint32_t> pci_dev;
Param<uint32_t> pci_func;
+ Param<Tick> pio_latency;
+ Param<Tick> intr_delay;
- SimObjectParam<HierParams *> hier;
- SimObjectParam<Bus*> pio_bus;
- SimObjectParam<Bus*> dma_bus;
- SimObjectParam<Bus*> payload_bus;
+ Param<Tick> clock;
Param<Tick> dma_read_delay;
Param<Tick> dma_read_factor;
Param<Tick> dma_write_delay;
Param<Tick> dma_write_factor;
- Param<bool> dma_no_allocate;
- Param<Tick> pio_latency;
- Param<Tick> intr_delay;
Param<Tick> rx_delay;
Param<Tick> tx_delay;
Param<uint32_t> tx_fifo_threshold;
Param<bool> rx_filter;
- Param<string> hardware_address;
+ Param<std::string> hardware_address;
Param<bool> rx_thread;
Param<bool> tx_thread;
Param<bool> rss;
BEGIN_INIT_SIM_OBJECT_PARAMS(Device)
- INIT_PARAM(clock, "State machine cycle time"),
- INIT_PARAM(addr, "Device Address"),
- INIT_PARAM(mmu, "Memory Controller"),
- INIT_PARAM(physmem, "Physical Memory"),
+ INIT_PARAM(system, "System pointer"),
+ INIT_PARAM(platform, "Platform pointer"),
INIT_PARAM(configspace, "PCI Configspace"),
INIT_PARAM(configdata, "PCI Config data"),
- INIT_PARAM(platform, "Platform"),
- INIT_PARAM(pci_bus, "PCI bus"),
+ INIT_PARAM(pci_bus, "PCI bus ID"),
INIT_PARAM(pci_dev, "PCI device number"),
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_factor, "multiplier for dma reads"),
INIT_PARAM(dma_write_delay, "fixed delay 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(tx_delay, "Transmit Delay"),
CREATE_SIM_OBJECT(Device)
{
Device::Params *params = new Device::Params;
-
params->name = getInstanceName();
-
- params->clock = clock;
-
- params->mmu = mmu;
- params->physmem = physmem;
+ params->platform = platform;
+ params->system = system;
params->configSpace = configspace;
params->configData = configdata;
- params->plat = platform;
params->busNum = pci_bus;
params->deviceNum = pci_dev;
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_factor = dma_read_factor;
params->dma_write_delay = dma_write_delay;
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->rx_delay = rx_delay;
#include "dev/pcidev.hh"
#include "dev/pktfifo.hh"
#include "dev/sinicreg.hh"
-#include "mem/bus/bus.hh"
#include "sim/eventq.hh"
namespace Sinic {
class Device : public Base
{
- protected:
- Platform *plat;
- PhysicalMemory *physmem;
-
protected:
/** Receive State Machine States */
enum RxState {
uint32_t ®Data32(Addr daddr) { return *(uint32_t *)®Data8(daddr); }
uint64_t ®Data64(Addr daddr) { return *(uint64_t *)®Data8(daddr); }
- private:
- Addr addr;
- static const Addr size = Regs::Size;
-
protected:
RxState rxState;
PacketFifo rxFifo;
TxState txState;
PacketFifo txFifo;
bool txFull;
- PacketPtr txPacket;
+ EthPacketPtr txPacket;
int txPacketOffset;
int txPacketBytes;
Addr txDmaAddr;
/**
* receive address filter
*/
- bool rxFilter(const PacketPtr &packet);
+ bool rxFilter(const EthPacketPtr &packet);
/**
* device configuration
* device ethernet interface
*/
public:
- bool recvPacket(PacketPtr packet);
+ bool recvPacket(EthPacketPtr packet);
void transferDone();
void setInterface(Interface *i) { assert(!interface); interface = i; }
* DMA parameters
*/
protected:
- void rxDmaCopy();
void rxDmaDone();
friend class EventWrapper<Device, &Device::rxDmaDone>;
EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
- void txDmaCopy();
void txDmaDone();
friend class EventWrapper<Device, &Device::txDmaDone>;
EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
void devIntrClear(uint32_t interrupts = Regs::Intr_All);
void devIntrChangeMask(uint32_t newmask);
-/**
- * PCI Configuration interface
- */
- public:
- virtual void writeConfig(int offset, int size, const uint8_t *data);
-
/**
* Memory Interface
*/
public:
- virtual Fault read(MemReqPtr &req, uint8_t *data);
- virtual Fault write(MemReqPtr &req, const uint8_t *data);
+ virtual Tick read(Packet &pkt);
+ virtual Tick write(Packet &pkt);
void prepareIO(int cpu, int index);
void prepareRead(int cpu, int index);
void prepareWrite(int cpu, int index);
- 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);
+ // Fault iprRead(Addr daddr, int cpu, uint64_t &result);
/**
* Statistics
public:
struct Params : public Base::Params
{
- IntrControl *i;
- PhysicalMemory *pmem;
Tick tx_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;
Net::EthAddr eaddr;
uint32_t rx_max_copy;
Tick dma_read_factor;
Tick dma_write_delay;
Tick dma_write_factor;
- bool dma_no_allocate;
bool rx_thread;
bool tx_thread;
bool rss;
Interface(const std::string &name, Device *d)
: 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(); }
};
Addr regnum = (pkt.addr - pioAddr) >> 6;
Addr daddr = (pkt.addr - pioAddr);
- uint64_t *data64;
-
+ pkt.allocate();
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 (daddr & TSDEV_CC_BDIMS)
{
- *data64 = dim[(daddr >> 4) & 0x3F];
+ pkt.set(dim[(daddr >> 4) & 0x3F]);
break;
}
if (daddr & TSDEV_CC_BDIRS)
{
- *data64 = dir[(daddr >> 4) & 0x3F];
+ pkt.set(dir[(daddr >> 4) & 0x3F]);
break;
}
switch(regnum) {
case TSDEV_CC_CSR:
- *data64 = 0x0;
+ pkt.set(0x0);
break;
case TSDEV_CC_MTR:
panic("TSDEV_CC_MTR not implemeted\n");
break;
case TSDEV_CC_MISC:
- *data64 = (ipint << 8) & 0xF | (itint << 4) & 0xF |
- (pkt.req->getCpuNum() & 0x3);
+ pkt.set((ipint << 8) & 0xF | (itint << 4) & 0xF |
+ (pkt.req->getCpuNum() & 0x3));
break;
case TSDEV_CC_AAR0:
case TSDEV_CC_AAR1:
case TSDEV_CC_AAR2:
case TSDEV_CC_AAR3:
- *data64 = 0;
+ pkt.set(0);
break;
case TSDEV_CC_DIM0:
- *data64 = dim[0];
+ pkt.set(dim[0]);
break;
case TSDEV_CC_DIM1:
- *data64 = dim[1];
+ pkt.set(dim[1]);
break;
case TSDEV_CC_DIM2:
- *data64 = dim[2];
+ pkt.set(dim[2]);
break;
case TSDEV_CC_DIM3:
- *data64 = dim[3];
+ pkt.set(dim[3]);
break;
case TSDEV_CC_DIR0:
- *data64 = dir[0];
+ pkt.set(dir[0]);
break;
case TSDEV_CC_DIR1:
- *data64 = dir[1];
+ pkt.set(dir[1]);
break;
case TSDEV_CC_DIR2:
- *data64 = dir[2];
+ pkt.set(dir[2]);
break;
case TSDEV_CC_DIR3:
- *data64 = dir[3];
+ pkt.set(dir[3]);
break;
case TSDEV_CC_DRIR:
- *data64 = drir;
+ pkt.set(drir);
break;
case TSDEV_CC_PRBEN:
panic("TSDEV_CC_PRBEN not implemented\n");
panic("TSDEV_CC_MPRx not implemented\n");
break;
case TSDEV_CC_IPIR:
- *data64 = ipint;
+ pkt.set(ipint);
break;
case TSDEV_CC_ITIR:
- *data64 = itint;
+ pkt.set(itint);
break;
default:
panic("default in cchip read reached, accessing 0x%x\n");
panic("invalid access size(?) for tsunami register!\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;
return pioDelay;
Addr regnum = (pkt.addr - pioAddr) >> 6 ;
- uint64_t val = *(uint64_t *)pkt.data;
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;
olddim = dim[number];
olddir = dir[number];
- dim[number] = val;
+ dim[number] = pkt.get<uint64_t>();
dir[number] = dim[number] & drir;
for(int x = 0; x < Tsunami::Max_CPUs; x++)
{
panic("TSDEV_CC_MTR write not implemented\n");
case TSDEV_CC_MISC:
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 (ipreq) {
reqIPI(ipreq);
//If it is bit 8-11, this is an IPI clear
uint64_t ipintr;
- ipintr = (val >> 8) & 0xF;
+ ipintr = (pkt.get<uint64_t>() >> 8) & 0xF;
if (ipintr) {
clearIPI(ipintr);
supportedWrite = true;
//If it is the 4-7th bit, clear the RTC interrupt
uint64_t itintr;
- itintr = (val >> 4) & 0xF;
+ itintr = (pkt.get<uint64_t>() >> 4) & 0xF;
if (itintr) {
clearITI(itintr);
supportedWrite = true;
}
// ignore NXMs
- if (val & 0x10000000)
+ if (pkt.get<uint64_t>() & 0x10000000)
supportedWrite = true;
if(!supportedWrite)
olddim = dim[number];
olddir = dir[number];
- dim[number] = val;
+ dim[number] = pkt.get<uint64_t>();
dir[number] = dim[number] & drir;
for(int x = 0; x < 64; x++)
{
case TSDEV_CC_MPR3:
panic("TSDEV_CC_MPRx write not implemented\n");
case TSDEV_CC_IPIR:
- clearIPI(val);
+ clearIPI(pkt.get<uint64_t>());
break;
case TSDEV_CC_ITIR:
- clearITI(val);
+ clearITI(pkt.get<uint64_t>());
break;
case TSDEV_CC_IPIQ:
- reqIPI(val);
+ reqIPI(pkt.get<uint64_t>());
break;
default:
panic("default in cchip read reached, accessing 0x%x\n");
DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt.addr,
pkt.size, daddr);
-
- uint8_t *data8;
- uint64_t *data64;
+ pkt.allocate();
if (pkt.size == sizeof(uint8_t)) {
-
- if (!pkt.data) {
- data8 = new uint8_t;
- pkt.data = data8;
- } else
- data8 = pkt.data;
switch(daddr) {
// PIC1 mask read
case TSDEV_PIC1_MASK:
- *data8 = ~mask1;
+ pkt.set(~mask1);
break;
case TSDEV_PIC2_MASK:
- *data8 = ~mask2;
+ pkt.set(~mask2);
break;
case TSDEV_PIC1_ISR:
// !!! If this is modified 64bit case needs to be too
// Pal code has to do a 64 bit physical read because there is
// no load physical byte instruction
- *data8 = picr;
+ pkt.set(picr);
break;
case TSDEV_PIC2_ISR:
// PIC2 not implemnted... just return 0
- *data8 = 0x00;
+ pkt.set(0x00);
break;
case TSDEV_TMR0_DATA:
- pitimer.counter0.read(data8);
+ pitimer.counter0.read(pkt.getPtr<uint8_t>());
break;
case TSDEV_TMR1_DATA:
- pitimer.counter1.read(data8);
+ pitimer.counter1.read(pkt.getPtr<uint8_t>());
break;
case TSDEV_TMR2_DATA:
- pitimer.counter2.read(data8);
+ pitimer.counter2.read(pkt.getPtr<uint8_t>());
break;
case TSDEV_RTC_DATA:
- rtc.readData(data8);
+ rtc.readData(pkt.getPtr<uint8_t>());
break;
case TSDEV_CTRL_PORTB:
if (pitimer.counter2.outputHigh())
- *data8 = PORTB_SPKR_HIGH;
+ pkt.set(PORTB_SPKR_HIGH);
else
- *data8 = 0x00;
+ pkt.set(0x00);
break;
default:
panic("I/O Read - va%#x size %d\n", pkt.addr, pkt.size);
}
} 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)
- *data64 = picr;
+ pkt.set<uint64_t>(picr);
else
panic("I/O Read - invalid addr - va %#x size %d\n",
pkt.addr, pkt.size);
assert(pkt.result == Unknown);
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
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",
- 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));
switch(daddr) {
case TSDEV_PIC1_MASK:
- mask1 = ~(val);
+ mask1 = ~(pkt.get<uint8_t>());
if ((picr & mask1) && !picInterrupting) {
picInterrupting = true;
tsunami->cchip->postDRIR(55);
}
break;
case TSDEV_PIC2_MASK:
- mask2 = val;
+ mask2 = pkt.get<uint8_t>();
//PIC2 Not implemented to interrupt
break;
case TSDEV_PIC1_ACK:
// clear the interrupt on the PIC
- picr &= ~(1 << (val & 0xF));
+ picr &= ~(1 << (pkt.get<uint8_t>() & 0xF));
if (!(picr & mask1))
tsunami->cchip->clearDRIR(55);
break;
case TSDEV_DMA1_MODE:
- mode1 = val;
+ mode1 = pkt.get<uint8_t>();
break;
case TSDEV_DMA2_MODE:
- mode2 = val;
+ mode2 = pkt.get<uint8_t>();
break;
case TSDEV_TMR0_DATA:
- pitimer.counter0.write(val);
+ pitimer.counter0.write(pkt.get<uint8_t>());
break;
case TSDEV_TMR1_DATA:
- pitimer.counter1.write(val);
+ pitimer.counter1.write(pkt.get<uint8_t>());
break;
case TSDEV_TMR2_DATA:
- pitimer.counter2.write(val);
+ pitimer.counter2.write(pkt.get<uint8_t>());
break;
case TSDEV_TMR_CTRL:
- pitimer.writeControl(val);
+ pitimer.writeControl(pkt.get<uint8_t>());
break;
case TSDEV_RTC_ADDR:
- rtc.writeAddr(val);
+ rtc.writeAddr(pkt.get<uint8_t>());
break;
case TSDEV_RTC_DATA:
- rtc.writeData(val);
+ rtc.writeData(pkt.get<uint8_t>());
break;
case TSDEV_KBD:
case TSDEV_DMA1_CMND:
case TSDEV_CTRL_PORTB:
break;
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;
assert(pkt.result == Unknown);
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
+
pkt.time = curTick + pioDelay;
+ pkt.allocate();
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);
switch(daddr) {
case TSDEV_PC_WSBA0:
- *data64 = wsba[0];
+ pkt.set(wsba[0]);
break;
case TSDEV_PC_WSBA1:
- *data64 = wsba[1];
+ pkt.set(wsba[1]);
break;
case TSDEV_PC_WSBA2:
- *data64 = wsba[2];
+ pkt.set(wsba[2]);
break;
case TSDEV_PC_WSBA3:
- *data64 = wsba[3];
+ pkt.set(wsba[3]);
break;
case TSDEV_PC_WSM0:
- *data64 = wsm[0];
+ pkt.set(wsm[0]);
break;
case TSDEV_PC_WSM1:
- *data64 = wsm[1];
+ pkt.set(wsm[1]);
break;
case TSDEV_PC_WSM2:
- *data64 = wsm[2];
+ pkt.set(wsm[2]);
break;
case TSDEV_PC_WSM3:
- *data64 = wsm[3];
+ pkt.set(wsm[3]);
break;
case TSDEV_PC_TBA0:
- *data64 = tba[0];
+ pkt.set(tba[0]);
break;
case TSDEV_PC_TBA1:
- *data64 = tba[1];
+ pkt.set(tba[1]);
break;
case TSDEV_PC_TBA2:
- *data64 = tba[2];
+ pkt.set(tba[2]);
break;
case TSDEV_PC_TBA3:
- *data64 = tba[3];
+ pkt.set(tba[3]);
break;
case TSDEV_PC_PCTL:
- *data64 = pctl;
+ pkt.set(pctl);
break;
case TSDEV_PC_PLAT:
panic("PC_PLAT not implemented\n");
case TSDEV_PC_RES:
panic("PC_RES not implemented\n");
case TSDEV_PC_PERROR:
- *data64 = 0x00;
+ pkt.set((uint64_t)0x00);
break;
case TSDEV_PC_PERRMASK:
- *data64 = 0x00;
+ pkt.set((uint64_t)0x00);
break;
case TSDEV_PC_PERRSET:
panic("PC_PERRSET not implemented\n");
case TSDEV_PC_TLBIV:
panic("PC_TLBIV not implemented\n");
case TSDEV_PC_TLBIA:
- *data64 = 0x00; // shouldn't be readable, but linux
+ pkt.set((uint64_t)0x00); // shouldn't be readable, but linux
break;
case TSDEV_PC_PMONCTL:
panic("PC_PMONCTL not implemented\n");
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
Addr daddr = (pkt.addr - pioAddr) >> 6;
- uint64_t data64 = *(uint64_t *)pkt.data;
assert(pkt.size == sizeof(uint64_t));
DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt.addr, pkt.size);
switch(daddr) {
case TSDEV_PC_WSBA0:
- wsba[0] = data64;
+ wsba[0] = pkt.get<uint64_t>();
break;
case TSDEV_PC_WSBA1:
- wsba[1] = data64;
+ wsba[1] = pkt.get<uint64_t>();
break;
case TSDEV_PC_WSBA2:
- wsba[2] = data64;
+ wsba[2] = pkt.get<uint64_t>();
break;
case TSDEV_PC_WSBA3:
- wsba[3] = data64;
+ wsba[3] = pkt.get<uint64_t>();
break;
case TSDEV_PC_WSM0:
- wsm[0] = data64;
+ wsm[0] = pkt.get<uint64_t>();
break;
case TSDEV_PC_WSM1:
- wsm[1] = data64;
+ wsm[1] = pkt.get<uint64_t>();
break;
case TSDEV_PC_WSM2:
- wsm[2] = data64;
+ wsm[2] = pkt.get<uint64_t>();
break;
case TSDEV_PC_WSM3:
- wsm[3] = data64;
+ wsm[3] = pkt.get<uint64_t>();
break;
case TSDEV_PC_TBA0:
- tba[0] = data64;
+ tba[0] = pkt.get<uint64_t>();
break;
case TSDEV_PC_TBA1:
- tba[1] = data64;
+ tba[1] = pkt.get<uint64_t>();
break;
case TSDEV_PC_TBA2:
- tba[2] = data64;
+ tba[2] = pkt.get<uint64_t>();
break;
case TSDEV_PC_TBA3:
- tba[3] = data64;
+ tba[3] = pkt.get<uint64_t>();
break;
case TSDEV_PC_PCTL:
- pctl = data64;
+ pctl = pkt.get<uint64_t>();
break;
case TSDEV_PC_PLAT:
panic("PC_PLAT not implemented\n");
pkt.time = curTick + pioDelay;
Addr daddr = pkt.addr - pioAddr;
- uint8_t *data;
+ pkt.allocate();
DPRINTF(Uart, " read register %#x\n", daddr);
- if (!pkt.data) {
- data = new uint8_t;
- pkt.data = data;
- } else
- data = pkt.data;
-
switch (daddr) {
case 0x0:
if (!(LCR & 0x80)) { // read byte
if (cons->dataAvailable())
- cons->in(*data);
+ cons->in(*pkt.getPtr<uint8_t>());
else {
- *data = 0;
+ pkt.set((uint8_t)0);
// A limited amount of these are ok.
DPRINTF(Uart, "empty read of RX register\n");
}
break;
case 0x1:
if (!(LCR & 0x80)) { // Intr Enable Register(IER)
- *data = IER;
+ pkt.set(IER);
} else { // DLM divisor latch MSB
;
}
DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status);
if (status & RX_INT) /* Rx data interrupt has a higher priority */
- *data = IIR_RXID;
+ pkt.set(IIR_RXID);
else if (status & TX_INT)
- *data = IIR_TXID;
+ pkt.set(IIR_TXID);
else
- *data = IIR_NOPEND;
+ pkt.set(IIR_NOPEND);
//Tx interrupts are cleared on IIR reads
status &= ~TX_INT;
break;
case 0x3: // Line Control Register (LCR)
- *data = LCR;
+ pkt.set(LCR);
break;
case 0x4: // Modem Control Register (MCR)
break;
if (cons->dataAvailable())
lsr = UART_LSR_DR;
lsr |= UART_LSR_TEMT | UART_LSR_THRE;
- *data = lsr;
+ pkt.set(lsr);
break;
case 0x6: // Modem Status Register (MSR)
- *data = 0;
+ pkt.set((uint8_t)0);
break;
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;
default:
panic("Tried to access a UART port that doesn't exist\n");
pkt.time = curTick + pioDelay;
Addr daddr = pkt.addr - pioAddr;
- uint8_t *data = pkt.data;
-
- DPRINTF(Uart, " write register %#x value %#x\n", daddr, *data);
+ DPRINTF(Uart, " write register %#x value %#x\n", daddr, pkt.get<uint8_t>());
switch (daddr) {
case 0x0:
if (!(LCR & 0x80)) { // write byte
- cons->out(*data);
+ cons->out(pkt.get<uint8_t>());
platform->clearConsoleInt();
status &= ~TX_INT;
if (UART_IER_THRI & IER)
break;
case 0x1:
if (!(LCR & 0x80)) { // Intr Enable Register(IER)
- IER = *data;
+ IER = pkt.get<uint8_t>();
if (UART_IER_THRI & IER)
{
DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n");
case 0x2: // FIFO Control Register (FCR)
break;
case 0x3: // Line Control Register (LCR)
- LCR = *data;
+ LCR = pkt.get<uint8_t>();
break;
case 0x4: // Modem Control Register (MCR)
- if (*data == (UART_MCR_LOOP | 0x0A))
+ if (pkt.get<uint8_t>() == (UART_MCR_LOOP | 0x0A))
MCR = 0x9A;
break;
case 0x7: // Scratch Register (SCR)
* bit 2:1 ID of highest priority interrupt
* bit 7:3 zeroes
*/
-#define IIR_NOPEND 0x1
+const uint8_t IIR_NOPEND = 0x1;
// Interrupt IDs
-#define IIR_MODEM 0x00 /* Modem Status (lowest priority) */
-#define IIR_TXID 0x02 /* Tx Data */
-#define IIR_RXID 0x04 /* Rx Data */
-#define IIR_LINE 0x06 /* Rx Line Status (highest priority)*/
+const uint8_t IIR_MODEM = 0x00; /* Modem Status (lowest priority) */
+const uint8_t IIR_TXID = 0x02; /* Tx Data */
+const uint8_t IIR_RXID = 0x04; /* Rx Data */
+const uint8_t IIR_LINE = 0x06; /* Rx Line Status (highest priority)*/
class SimConsole;
class Platform;
*/
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
cache configurations). */
Addr addr;
void *senderState; // virtual base opaque,
// assert(dynamic_cast<Foo>) etc.
- /** 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 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. */
+ /** Indicates the size of the request. */
int size;
/** A index of the source of the transaction. */
short getDest() const { return dest; }
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
switch (pkt.cmd) {
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;
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;
default:
panic("unimplemented");
!gen.done(); gen.next()) {
req.setPaddr(pkt.addr = gen.addr());
req.setSize(pkt.size = gen.size());
- pkt.data = p;
+ pkt.dataStatic(p);
sendFunctional(pkt);
p += gen.size();
}
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_factor = Param.Latency('0us', "multiplier for dma reads")
dma_write_delay = Param.Latency('0us', "fixed delay 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")
tx_delay = Param.Latency('1us', "Transmit Delay")
dma_data_free = Param.Bool(False, "DMA of Data is free")
dma_desc_free = Param.Bool(False, "DMA of Descriptors is free")
+ dma_no_allocate = Param.Bool(True, "Should we allocate cache on read")
class NSGigEInt(EtherInt):