summaryrefslogtreecommitdiff
path: root/dev
diff options
context:
space:
mode:
Diffstat (limited to 'dev')
-rw-r--r--dev/alpha_console.cc56
-rw-r--r--dev/etherbus.cc2
-rw-r--r--dev/etherbus.hh4
-rw-r--r--dev/etherdump.cc2
-rw-r--r--dev/etherdump.hh4
-rw-r--r--dev/etherint.hh4
-rw-r--r--dev/etherlink.cc14
-rw-r--r--dev/etherlink.hh8
-rw-r--r--dev/etherpkt.cc4
-rw-r--r--dev/etherpkt.hh12
-rw-r--r--dev/ethertap.cc8
-rw-r--r--dev/ethertap.hh6
-rw-r--r--dev/ide_ctrl.cc429
-rw-r--r--dev/ide_ctrl.hh45
-rw-r--r--dev/ide_disk.cc290
-rw-r--r--dev/ide_disk.hh23
-rw-r--r--dev/io_device.cc56
-rw-r--r--dev/io_device.hh49
-rw-r--r--dev/isa_fake.cc38
-rw-r--r--dev/ns_gige.cc695
-rw-r--r--dev/ns_gige.hh42
-rw-r--r--dev/pciconfigall.cc74
-rw-r--r--dev/pciconfigall.hh2
-rw-r--r--dev/pcidev.cc318
-rw-r--r--dev/pcidev.hh102
-rw-r--r--dev/pktfifo.cc10
-rw-r--r--dev/pktfifo.hh12
-rw-r--r--dev/sinic.cc334
-rw-r--r--dev/sinic.hh44
-rw-r--r--dev/tsunami_cchip.cc66
-rw-r--r--dev/tsunami_io.cc69
-rw-r--r--dev/tsunami_pchip.cc69
-rw-r--r--dev/uart8250.cc40
-rw-r--r--dev/uart8250.hh10
34 files changed, 1145 insertions, 1796 deletions
diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc
index fde8af6ae..e05337bfa 100644
--- a/dev/alpha_console.cc
+++ b/dev/alpha_console.cc
@@ -102,31 +102,24 @@ AlphaConsole::read(Packet &pkt)
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
@@ -134,62 +127,59 @@ AlphaConsole::read(Packet &pkt)
*/
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;
@@ -207,7 +197,7 @@ AlphaConsole::write(Packet &pkt)
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) {
diff --git a/dev/etherbus.cc b/dev/etherbus.cc
index c6b131e8e..906e324d3 100644
--- a/dev/etherbus.cc
+++ b/dev/etherbus.cc
@@ -81,7 +81,7 @@ EtherBus::reg(EtherInt *dev)
{ 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);
diff --git a/dev/etherbus.hh b/dev/etherbus.hh
index ca859d85f..4a364abd8 100644
--- a/dev/etherbus.hh
+++ b/dev/etherbus.hh
@@ -61,7 +61,7 @@ class EtherBus : public SimObject
};
DoneEvent event;
- PacketPtr packet;
+ EthPacketPtr packet;
EtherInt *sender;
EtherDump *dump;
@@ -73,7 +73,7 @@ class EtherBus : public SimObject
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__
diff --git a/dev/etherdump.cc b/dev/etherdump.cc
index d8a51fc5b..cb5f0b70e 100644
--- a/dev/etherdump.cc
+++ b/dev/etherdump.cc
@@ -102,7 +102,7 @@ EtherDump::init()
}
void
-EtherDump::dumpPacket(PacketPtr &packet)
+EtherDump::dumpPacket(EthPacketPtr &packet)
{
pcap_pkthdr pkthdr;
pkthdr.seconds = curtime + (curTick / Clock::Int::s);
diff --git a/dev/etherdump.hh b/dev/etherdump.hh
index 149192cd7..8bba073fe 100644
--- a/dev/etherdump.hh
+++ b/dev/etherdump.hh
@@ -45,7 +45,7 @@ class EtherDump : public SimObject
private:
std::ofstream stream;
const int maxlen;
- void dumpPacket(PacketPtr &packet);
+ void dumpPacket(EthPacketPtr &packet);
void init();
Tick curtime;
@@ -53,7 +53,7 @@ class EtherDump : public SimObject
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__
diff --git a/dev/etherint.hh b/dev/etherint.hh
index e397846ae..1f641fadb 100644
--- a/dev/etherint.hh
+++ b/dev/etherint.hh
@@ -58,9 +58,9 @@ class EtherInt : public SimObject
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__
diff --git a/dev/etherlink.cc b/dev/etherlink.cc
index f68332926..5b6531c2e 100644
--- a/dev/etherlink.cc
+++ b/dev/etherlink.cc
@@ -102,7 +102,7 @@ EtherLink::unserialize(Checkpoint *cp, const string &section)
}
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);
@@ -113,12 +113,12 @@ class LinkDelayEvent : public Event
{
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();
@@ -148,7 +148,7 @@ EtherLink::Link::txDone()
}
bool
-EtherLink::Link::transmit(PacketPtr pkt)
+EtherLink::Link::transmit(EthPacketPtr pkt)
{
if (busy()) {
DPRINTF(Ethernet, "packet not sent, link busy\n");
@@ -195,7 +195,7 @@ EtherLink::Link::unserialize(const string &base, Checkpoint *cp,
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);
}
@@ -215,7 +215,7 @@ LinkDelayEvent::LinkDelayEvent()
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);
@@ -256,7 +256,7 @@ LinkDelayEvent::unserialize(Checkpoint *cp, const string &section)
link = parent->link[number];
- packet = new PacketData(16384);
+ packet = new EthPacketData(16384);
packet->unserialize("packet", cp, section);
}
diff --git a/dev/etherlink.hh b/dev/etherlink.hh
index 305007d9e..570444e1b 100644
--- a/dev/etherlink.hh
+++ b/dev/etherlink.hh
@@ -73,14 +73,14 @@ class EtherLink : public SimObject
/*
* 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,
@@ -90,7 +90,7 @@ class EtherLink : public SimObject
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; }
@@ -110,7 +110,7 @@ class EtherLink : public SimObject
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(); }
};
diff --git a/dev/etherpkt.cc b/dev/etherpkt.cc
index 44dbd7c18..85e18e981 100644
--- a/dev/etherpkt.cc
+++ b/dev/etherpkt.cc
@@ -35,7 +35,7 @@
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);
@@ -43,7 +43,7 @@ PacketData::serialize(const string &base, ostream &os)
}
void
-PacketData::unserialize(const string &base, Checkpoint *cp,
+EthPacketData::unserialize(const string &base, Checkpoint *cp,
const string &section)
{
paramIn(cp, section, base + ".length", length);
diff --git a/dev/etherpkt.hh b/dev/etherpkt.hh
index cb9022d72..01741b3d5 100644
--- a/dev/etherpkt.hh
+++ b/dev/etherpkt.hh
@@ -44,7 +44,7 @@
* Reference counted class containing ethernet packet data
*/
class Checkpoint;
-class PacketData : public RefCounted
+class EthPacketData : public RefCounted
{
public:
/*
@@ -66,12 +66,12 @@ class PacketData : public RefCounted
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);
@@ -79,6 +79,6 @@ class PacketData : public RefCounted
const std::string &section);
};
-typedef RefCountingPtr<PacketData> PacketPtr;
+typedef RefCountingPtr<EthPacketData> EthPacketPtr;
#endif // __ETHERPKT_HH__
diff --git a/dev/ethertap.cc b/dev/ethertap.cc
index 7589991ef..b5abb1d62 100644
--- a/dev/ethertap.cc
+++ b/dev/ethertap.cc
@@ -169,7 +169,7 @@ EtherTap::detach()
}
bool
-EtherTap::recvPacket(PacketPtr packet)
+EtherTap::recvPacket(EthPacketPtr packet)
{
if (dump)
dump->dump(packet);
@@ -218,8 +218,8 @@ EtherTap::process(int revent)
}
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);
@@ -250,7 +250,7 @@ EtherTap::retransmit()
if (packetBuffer.empty())
return;
- PacketPtr packet = packetBuffer.front();
+ EthPacketPtr packet = packetBuffer.front();
if (sendPacket(packet)) {
if (dump)
dump->dump(packet);
diff --git a/dev/ethertap.hh b/dev/ethertap.hh
index 069ba734f..40ce6af0b 100644
--- a/dev/ethertap.hh
+++ b/dev/ethertap.hh
@@ -70,10 +70,10 @@ class EtherTap : public EtherInt
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();
/*
@@ -97,7 +97,7 @@ class EtherTap : public EtherInt
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);
diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc
index fed604867..638be9c3d 100644
--- a/dev/ide_ctrl.cc
+++ b/dev/ide_ctrl.cc
@@ -31,7 +31,6 @@
#include <string>
#include <vector>
-#include "arch/alpha/ev5.hh"
#include "base/trace.hh"
#include "cpu/intr_control.hh"
#include "dev/ide_ctrl.hh"
@@ -39,17 +38,12 @@
#include "dev/pciconfigall.hh"
#include "dev/pcireg.h"
#include "dev/platform.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/sim_object.hh"
+#include "sim/byteswap.hh"
using namespace std;
-using namespace TheISA;
////
// Initialization and destruction
@@ -92,22 +86,6 @@ IdeController::IdeController(Params *p)
bm_enabled = false;
memset(cmd_in_progress, 0, sizeof(cmd_in_progress));
- pioInterface = NULL;
- dmaInterface = NULL;
- // create the PIO and DMA interfaces
- if (params()->pio_bus) {
- pioInterface = newPioInterface(name() + ".pio", params()->hier,
- params()->pio_bus, this,
- &IdeController::cacheAccess);
- pioLatency = params()->pio_latency * params()->pio_bus->clockRate;
- }
-
- if (params()->dma_bus) {
- dmaInterface = new DMAInterface<Bus>(name() + ".dma",
- params()->dma_bus,
- params()->dma_bus, 1, true);
- }
-
// setup the disks attached to controller
memset(disks, 0, sizeof(disks));
dev[0] = 0;
@@ -118,7 +96,7 @@ IdeController::IdeController(Params *p)
for (int i = 0; i < params()->disks.size(); i++) {
disks[i] = params()->disks[i];
- disks[i]->setController(this, dmaInterface);
+ disks[i]->setController(this);
}
}
@@ -240,91 +218,158 @@ IdeController::setDmaComplete(IdeDisk *disk)
}
}
-////
-// Bus timing and bus access functions
-////
-
-Tick
-IdeController::cacheAccess(MemReqPtr &req)
-{
- // @todo Add more accurate timing to cache access
- return curTick + pioLatency;
-}
////
// Read and write handling
////
void
-IdeController::readConfig(int offset, int size, uint8_t *data)
+IdeController::readConfig(int offset, uint8_t *data)
{
- int config_offset;
-
if (offset < PCI_DEVICE_SPECIFIC) {
- PciDev::readConfig(offset, size, data);
+ PciDev::readConfig(offset, data);
} else if (offset >= IDE_CTRL_CONF_START &&
- (offset + size) <= IDE_CTRL_CONF_END) {
-
- config_offset = offset - IDE_CTRL_CONF_START;
+ (offset + 1) <= IDE_CTRL_CONF_END) {
- switch (size) {
- case sizeof(uint8_t):
- *data = config_regs.data[config_offset];
+ switch (offset) {
+ case IDE_CTRL_CONF_DEV_TIMING:
+ *data = config_regs.sidetim;
break;
- case sizeof(uint16_t):
- *(uint16_t*)data = *(uint16_t*)&config_regs.data[config_offset];
+ case IDE_CTRL_CONF_UDMA_CNTRL:
+ *data = config_regs.udmactl;
break;
- case sizeof(uint32_t):
- *(uint32_t*)data = *(uint32_t*)&config_regs.data[config_offset];
+ case IDE_CTRL_CONF_PRIM_TIMING+1:
+ *data = htole(config_regs.idetim0) >> 8;
+ break;
+ case IDE_CTRL_CONF_SEC_TIMING+1:
+ *data = htole(config_regs.idetim1) >> 8;
+ break;
+ case IDE_CTRL_CONF_IDE_CONFIG:
+ *data = htole(config_regs.ideconfig) & 0xFF;
+ break;
+ case IDE_CTRL_CONF_IDE_CONFIG+1:
+ *data = htole(config_regs.ideconfig) >> 8;
break;
default:
- panic("Invalid PCI configuration read size!\n");
+ panic("Invalid PCI configuration read for size 1 at offset: %#x!\n",
+ offset);
}
- DPRINTF(IdeCtrl, "PCI read offset: %#x size: %#x data: %#x\n",
- offset, size, *(uint32_t*)data);
-
} else {
panic("Read of unimplemented PCI config. register: %x\n", offset);
}
+ DPRINTF(IdeCtrl, "PCI read offset: %#x size: 1 data: %#x\n",
+ offset, (uint32_t)*data);
}
void
-IdeController::writeConfig(int offset, int size, const uint8_t *data)
+IdeController::readConfig(int offset, uint16_t *data)
{
- int config_offset;
+ if (offset < PCI_DEVICE_SPECIFIC) {
+ PciDev::readConfig(offset, data);
+ } else if (offset >= IDE_CTRL_CONF_START &&
+ (offset + 2) <= IDE_CTRL_CONF_END) {
+ switch (offset) {
+ case IDE_CTRL_CONF_PRIM_TIMING:
+ *data = config_regs.idetim0;
+ break;
+ case IDE_CTRL_CONF_SEC_TIMING:
+ *data = config_regs.idetim1;
+ break;
+ case IDE_CTRL_CONF_UDMA_TIMING:
+ *data = config_regs.udmatim;
+ break;
+ case IDE_CTRL_CONF_IDE_CONFIG:
+ *data = config_regs.ideconfig;
+ break;
+ default:
+ panic("Invalid PCI configuration read for size 2 offset: %#x!\n",
+ offset);
+ }
+
+ } else {
+ panic("Read of unimplemented PCI config. register: %x\n", offset);
+ }
+ DPRINTF(IdeCtrl, "PCI read offset: %#x size: 2 data: %#x\n", offset, *data);
+}
+
+void
+IdeController::readConfig(int offset, uint32_t *data)
+{
+ if (offset < PCI_DEVICE_SPECIFIC) {
+ PciDev::readConfig(offset, data);
+ } else {
+ panic("Read of unimplemented PCI config. register: %x\n", offset);
+ }
+ DPRINTF(IdeCtrl, "PCI read offset: %#x size: 4 data: %#x\n", offset, *data);
+}
+void
+IdeController::writeConfig(int offset, const uint8_t data)
+{
if (offset < PCI_DEVICE_SPECIFIC) {
- PciDev::writeConfig(offset, size, data);
+ PciDev::writeConfig(offset, data);
} else if (offset >= IDE_CTRL_CONF_START &&
- (offset + size) <= IDE_CTRL_CONF_END) {
+ (offset + 1) <= IDE_CTRL_CONF_END) {
+
+ switch (offset) {
+ case IDE_CTRL_CONF_DEV_TIMING:
+ config_regs.sidetim = data;
+ break;
+ case IDE_CTRL_CONF_UDMA_CNTRL:
+ config_regs.udmactl = data;
+ break;
+ case IDE_CTRL_CONF_IDE_CONFIG:
+ config_regs.ideconfig = (config_regs.ideconfig & 0xFF00) | (data);
+ break;
+ case IDE_CTRL_CONF_IDE_CONFIG+1:
+ config_regs.ideconfig = (config_regs.ideconfig & 0x00FF) | data << 8;
+ break;
+ default:
+ panic("Invalid PCI configuration write for size 1 offset: %#x!\n",
+ offset);
+ }
- config_offset = offset - IDE_CTRL_CONF_START;
+ } else {
+ panic("Read of unimplemented PCI config. register: %x\n", offset);
+ }
+ DPRINTF(IdeCtrl, "PCI write offset: %#x size: 1 data: %#x\n",
+ offset, (uint32_t)data);
+}
- switch(size) {
- case sizeof(uint8_t):
- config_regs.data[config_offset] = *data;
+void
+IdeController::writeConfig(int offset, const uint16_t data)
+{
+ if (offset < PCI_DEVICE_SPECIFIC) {
+ PciDev::writeConfig(offset, data);
+ } else if (offset >= IDE_CTRL_CONF_START &&
+ (offset + 2) <= IDE_CTRL_CONF_END) {
+
+ switch (offset) {
+ case IDE_CTRL_CONF_PRIM_TIMING:
+ config_regs.idetim0 = data;
break;
- case sizeof(uint16_t):
- *(uint16_t*)&config_regs.data[config_offset] = *(uint16_t*)data;
+ case IDE_CTRL_CONF_SEC_TIMING:
+ config_regs.idetim1 = data;
break;
- case sizeof(uint32_t):
- *(uint32_t*)&config_regs.data[config_offset] = *(uint32_t*)data;
+ case IDE_CTRL_CONF_UDMA_TIMING:
+ config_regs.udmatim = data;
+ break;
+ case IDE_CTRL_CONF_IDE_CONFIG:
+ config_regs.ideconfig = data;
break;
default:
- panic("Invalid PCI configuration write size!\n");
+ panic("Invalid PCI configuration write for size 2 offset: %#x!\n",
+ offset);
}
+
} else {
panic("Write of unimplemented PCI config. register: %x\n", offset);
}
+ DPRINTF(IdeCtrl, "PCI write offset: %#x size: 2 data: %#x\n", offset, data);
- DPRINTF(IdeCtrl, "PCI write offset: %#x size: %#x data: %#x\n",
- offset, size, data);
-
- // Catch the writes to specific PCI registers that have side affects
- // (like updating the PIO ranges)
- switch (offset) {
- case PCI_COMMAND:
+ /* Trap command register writes and enable IO/BM as appropriate. */
+ if (offset == PCI_COMMAND) {
if (letoh(config.command) & PCI_CMD_IOSE)
io_enabled = true;
else
@@ -334,91 +379,83 @@ IdeController::writeConfig(int offset, int size, const uint8_t *data)
bm_enabled = true;
else
bm_enabled = false;
- break;
+ }
+
+}
+
+void
+IdeController::writeConfig(int offset, const uint32_t data)
+{
+ if (offset < PCI_DEVICE_SPECIFIC) {
+ PciDev::writeConfig(offset, data);
+ } else {
+ panic("Read of unimplemented PCI config. register: %x\n", offset);
+ }
+
+ DPRINTF(IdeCtrl, "PCI write offset: %#x size: 4 data: %#x\n", offset, data);
+ switch(offset) {
case PCI0_BASE_ADDR0:
- if (BARAddrs[0] != 0) {
+ if (BARAddrs[0] != 0)
pri_cmd_addr = BARAddrs[0];
- if (pioInterface)
- pioInterface->addAddrRange(RangeSize(pri_cmd_addr,
- pri_cmd_size));
-
- pri_cmd_addr &= EV5::PAddrUncachedMask;
- }
break;
case PCI0_BASE_ADDR1:
- if (BARAddrs[1] != 0) {
+ if (BARAddrs[1] != 0)
pri_ctrl_addr = BARAddrs[1];
- if (pioInterface)
- pioInterface->addAddrRange(RangeSize(pri_ctrl_addr,
- pri_ctrl_size));
-
- pri_ctrl_addr &= EV5::PAddrUncachedMask;
- }
break;
case PCI0_BASE_ADDR2:
- if (BARAddrs[2] != 0) {
+ if (BARAddrs[2] != 0)
sec_cmd_addr = BARAddrs[2];
- if (pioInterface)
- pioInterface->addAddrRange(RangeSize(sec_cmd_addr,
- sec_cmd_size));
-
- sec_cmd_addr &= EV5::PAddrUncachedMask;
- }
break;
case PCI0_BASE_ADDR3:
- if (BARAddrs[3] != 0) {
+ if (BARAddrs[3] != 0)
sec_ctrl_addr = BARAddrs[3];
- if (pioInterface)
- pioInterface->addAddrRange(RangeSize(sec_ctrl_addr,
- sec_ctrl_size));
-
- sec_ctrl_addr &= EV5::PAddrUncachedMask;
- }
break;
case PCI0_BASE_ADDR4:
- if (BARAddrs[4] != 0) {
+ if (BARAddrs[4] != 0)
bmi_addr = BARAddrs[4];
- if (pioInterface)
- pioInterface->addAddrRange(RangeSize(bmi_addr, bmi_size));
-
- bmi_addr &= EV5::PAddrUncachedMask;
- }
break;
}
}
-Fault
-IdeController::read(MemReqPtr &req, uint8_t *data)
+Tick
+IdeController::read(Packet &pkt)
{
Addr offset;
IdeChannel channel;
IdeRegType reg_type;
int disk;
- parseAddr(req->paddr, offset, channel, reg_type);
+ 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);
- if (!io_enabled)
- return NoFault;
+ if (!io_enabled) {
+ pkt.result = Success;
+ return pioDelay;
+ }
switch (reg_type) {
case BMI_BLOCK:
- switch (req->size) {
+ switch (pkt.size) {
case sizeof(uint8_t):
- *data = bmi_regs.data[offset];
+ pkt.set(bmi_regs.data[offset]);
break;
case sizeof(uint16_t):
- *(uint16_t*)data = *(uint16_t*)&bmi_regs.data[offset];
+ pkt.set(*(uint16_t*)&bmi_regs.data[offset]);
break;
case sizeof(uint32_t):
- *(uint32_t*)data = *(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", req->size);
+ panic("IDE read of BMI reg invalid size: %#x\n", pkt.size);
}
break;
@@ -426,44 +463,54 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
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 (req->size) {
+ switch (pkt.size) {
case sizeof(uint16_t):
- disks[disk]->read(offset, reg_type, data);
+ disks[disk]->read(offset, reg_type, pkt.getPtr<uint8_t>());
break;
case sizeof(uint32_t):
- disks[disk]->read(offset, reg_type, data);
- disks[disk]->read(offset, reg_type, &data[2]);
+ 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:
- panic("IDE read of data reg invalid size: %#x\n", req->size);
+ panic("IDE read of data reg invalid size: %#x\n", pkt.size);
}
break;
default:
- if (req->size == sizeof(uint8_t)) {
- disks[disk]->read(offset, reg_type, data);
+ if (pkt.size == sizeof(uint8_t)) {
+ disks[disk]->read(offset, reg_type, pkt.getPtr<uint8_t>());
} else
- panic("IDE read of command reg of invalid size: %#x\n", req->size);
+ panic("IDE read of command reg of invalid size: %#x\n", pkt.size);
}
break;
default:
panic("IDE controller read of unknown register block type!\n");
}
-
+ if (pkt.size == 1)
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
- offset, req->size, *(uint32_t*)data);
+ 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, pkt.get<uint16_t>());
+ else
+ DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
+ offset, pkt.size, pkt.get<uint32_t>());
- return NoFault;
+ pkt.result = Success;
+ return pioDelay;
}
-Fault
-IdeController::write(MemReqPtr &req, const uint8_t *data)
+Tick
+IdeController::write(Packet &pkt)
{
Addr offset;
IdeChannel channel;
@@ -471,28 +518,35 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
int disk;
uint8_t oldVal, newVal;
- parseAddr(req->paddr, offset, channel, reg_type);
+ pkt.time = curTick + pioDelay;
- if (!io_enabled)
- return NoFault;
+ parseAddr(pkt.addr, offset, channel, reg_type);
+
+ if (!io_enabled) {
+ pkt.result = Success;
+ DPRINTF(IdeCtrl, "io not enabled\n");
+ return pioDelay;
+ }
switch (reg_type) {
case BMI_BLOCK:
- if (!bm_enabled)
- return NoFault;
+ if (!bm_enabled) {
+ pkt.result = Success;
+ return pioDelay;
+ }
switch (offset) {
// Bus master IDE command register
case BMIC1:
case BMIC0:
- if (req->size != sizeof(uint8_t))
- panic("Invalid BMIC write size: %x\n", req->size);
+ if (pkt.size != sizeof(uint8_t))
+ panic("Invalid BMIC write size: %x\n", pkt.size);
// select the current disk based on DEV bit
disk = getDisk(channel);
oldVal = bmi_regs.chan[channel].bmic;
- newVal = *data;
+ newVal = pkt.get<uint8_t>();
// if a DMA transfer is in progress, R/W control cannot change
if (oldVal & SSBM) {
@@ -541,11 +595,11 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
// Bus master IDE status register
case BMIS0:
case BMIS1:
- if (req->size != sizeof(uint8_t))
- panic("Invalid BMIS write size: %x\n", req->size);
+ if (pkt.size != sizeof(uint8_t))
+ panic("Invalid BMIS write size: %x\n", pkt.size);
oldVal = bmi_regs.chan[channel].bmis;
- newVal = *data;
+ newVal = pkt.get<uint8_t>();
// the BMIDEA bit is RO
newVal |= (oldVal & BMIDEA);
@@ -568,30 +622,28 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
case BMIDTP0:
case BMIDTP1:
{
- if (req->size != sizeof(uint32_t))
- panic("Invalid BMIDTP write size: %x\n", req->size);
+ if (pkt.size != sizeof(uint32_t))
+ panic("Invalid BMIDTP write size: %x\n", pkt.size);
- uint32_t host_data = letoh(*(uint32_t*)data);
- host_data &= ~0x3;
- bmi_regs.chan[channel].bmidtp = htole(host_data);
+ bmi_regs.chan[channel].bmidtp = htole(pkt.get<uint32_t>() & ~0x3);
}
break;
default:
- if (req->size != sizeof(uint8_t) &&
- req->size != sizeof(uint16_t) &&
- req->size != sizeof(uint32_t))
+ if (pkt.size != sizeof(uint8_t) &&
+ pkt.size != sizeof(uint16_t) &&
+ pkt.size != sizeof(uint32_t))
panic("IDE controller write of invalid write size: %x\n",
- req->size);
+ pkt.size);
// do a default copy of data into the registers
- memcpy(&bmi_regs.data[offset], data, req->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(*data) & IDE_SELECT_DEV_BIT) ? 1 : 0;
+ *devBit = (letoh(pkt.get<uint8_t>()) & IDE_SELECT_DEV_BIT) ? 1 : 0;
}
// fall-through ok!
case CONTROL_BLOCK:
@@ -602,34 +654,44 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
switch (offset) {
case DATA_OFFSET:
- switch (req->size) {
+ switch (pkt.size) {
case sizeof(uint16_t):
- disks[disk]->write(offset, reg_type, data);
+ disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>());
break;
case sizeof(uint32_t):
- disks[disk]->write(offset, reg_type, data);
- disks[disk]->write(offset, reg_type, &data[2]);
+ 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:
- panic("IDE write of data reg invalid size: %#x\n", req->size);
+ panic("IDE write of data reg invalid size: %#x\n", pkt.size);
}
break;
default:
- if (req->size == sizeof(uint8_t)) {
- disks[disk]->write(offset, reg_type, data);
+ if (pkt.size == sizeof(uint8_t)) {
+ disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>());
} else
- panic("IDE write of command reg of invalid size: %#x\n", req->size);
+ panic("IDE write of command reg of invalid size: %#x\n", pkt.size);
}
break;
default:
panic("IDE controller write of unknown register block type!\n");
}
+ if (pkt.size == 1)
+ DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
+ 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, req->size, *(uint32_t*)data);
+ offset, pkt.size, pkt.get<uint16_t>());
+ else
+ DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
+ offset, pkt.size, pkt.get<uint32_t>());
+
- return NoFault;
+ pkt.result = Success;
+ return pioDelay;
}
////
@@ -698,51 +760,36 @@ IdeController::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(bm_enabled);
UNSERIALIZE_ARRAY(cmd_in_progress,
sizeof(cmd_in_progress) / sizeof(cmd_in_progress[0]));
-
- if (pioInterface) {
- pioInterface->addAddrRange(RangeSize(pri_cmd_addr, pri_cmd_size));
- pioInterface->addAddrRange(RangeSize(pri_ctrl_addr, pri_ctrl_size));
- pioInterface->addAddrRange(RangeSize(sec_cmd_addr, sec_cmd_size));
- pioInterface->addAddrRange(RangeSize(sec_ctrl_addr, sec_ctrl_size));
- pioInterface->addAddrRange(RangeSize(bmi_addr, bmi_size));
- }
+ pioPort->sendStatusChange(Port::RangeChange);
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController)
- Param<Addr> addr;
- SimObjectVectorParam<IdeDisk *> disks;
- SimObjectParam<MemoryController *> mmu;
+ 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;
- SimObjectParam<Bus *> pio_bus;
- SimObjectParam<Bus *> dma_bus;
Param<Tick> pio_latency;
- SimObjectParam<HierParams *> hier;
+ SimObjectVectorParam<IdeDisk *> disks;
END_DECLARE_SIM_OBJECT_PARAMS(IdeController)
BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController)
- INIT_PARAM(addr, "Device Address"),
- INIT_PARAM(disks, "IDE disks attached to this controller"),
- INIT_PARAM(mmu, "Memory controller"),
+ 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 pointer"),
INIT_PARAM(pci_bus, "PCI bus ID"),
INIT_PARAM(pci_dev, "PCI device number"),
INIT_PARAM(pci_func, "PCI function code"),
- INIT_PARAM(pio_bus, ""),
- INIT_PARAM(dma_bus, ""),
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
- INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
+ INIT_PARAM(disks, "IDE disks attached to this controller")
END_INIT_SIM_OBJECT_PARAMS(IdeController)
@@ -750,19 +797,15 @@ CREATE_SIM_OBJECT(IdeController)
{
IdeController::Params *params = new IdeController::Params;
params->name = getInstanceName();
- params->mmu = mmu;
+ 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->disks = disks;
- params->pio_bus = pio_bus;
- params->dma_bus = dma_bus;
- params->pio_latency = pio_latency;
- params->hier = hier;
return new IdeController(params);
}
diff --git a/dev/ide_ctrl.hh b/dev/ide_ctrl.hh
index 0fbaf9207..a074f4f97 100644
--- a/dev/ide_ctrl.hh
+++ b/dev/ide_ctrl.hh
@@ -70,6 +70,13 @@
#define IDE_CTRL_CONF_START 0x40
#define IDE_CTRL_CONF_END ((IDE_CTRL_CONF_START) + sizeof(config_regs))
+#define IDE_CTRL_CONF_PRIM_TIMING 0x40
+#define IDE_CTRL_CONF_SEC_TIMING 0x42
+#define IDE_CTRL_CONF_DEV_TIMING 0x44
+#define IDE_CTRL_CONF_UDMA_CNTRL 0x48
+#define IDE_CTRL_CONF_UDMA_TIMING 0x4A
+#define IDE_CTRL_CONF_IDE_CONFIG 0x54
+
enum IdeRegType {
COMMAND_BLOCK,
@@ -77,13 +84,9 @@ enum IdeRegType {
BMI_BLOCK
};
-class BaseInterface;
-class Bus;
-class HierParams;
class IdeDisk;
class IntrControl;
class PciConfigAll;
-class PhysicalMemory;
class Platform;
/**
@@ -191,10 +194,6 @@ class IdeController : public PciDev
{
/** Array of disk objects */
std::vector<IdeDisk *> disks;
- Bus *pio_bus;
- Bus *dma_bus;
- Tick pio_latency;
- HierParams *hier;
};
const Params *params() const { return (const Params *)_params; }
@@ -202,26 +201,28 @@ class IdeController : public PciDev
IdeController(Params *p);
~IdeController();
- 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 uint8_t data);
+ virtual void writeConfig(int offset, const uint16_t data);
+ virtual void writeConfig(int offset, const uint32_t data);
+ virtual void readConfig(int offset, uint8_t *data);
+ virtual void readConfig(int offset, uint16_t *data);
+ virtual void readConfig(int offset, uint32_t *data);
void setDmaComplete(IdeDisk *disk);
/**
* Read a done field for a given target.
- * @param req Contains the address of the field to read.
- * @param data Return the field read.
- * @return The fault condition of the access.
+ * @param pkt Packet describing what is to be read
+ * @return The amount of time to complete this request
*/
- virtual Fault read(MemReqPtr &req, uint8_t *data);
+ virtual Tick read(Packet &pkt);
/**
- * Write to the mmapped I/O control registers.
- * @param req Contains the address to write to.
- * @param data The data to write.
- * @return The fault condition of the access.
+ * Write a done field for a given target.
+ * @param pkt Packet describing what is to be written
+ * @return The amount of time to complete this request
*/
- virtual Fault write(MemReqPtr &req, const uint8_t *data);
+ virtual Tick write(Packet &pkt);
/**
* Serialize this object to the given output stream.
@@ -236,11 +237,5 @@ class IdeController : public PciDev
*/
virtual void unserialize(Checkpoint *cp, const std::string &section);
- /**
- * Return how long this access will take.
- * @param req the memory request to calcuate
- * @return Tick when the request is done
- */
- Tick cacheAccess(MemReqPtr &req);
};
#endif // __IDE_CTRL_HH_
diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc
index 41400c590..6f4234a1d 100644
--- a/dev/ide_disk.cc
+++ b/dev/ide_disk.cc
@@ -35,6 +35,7 @@
#include <deque>
#include <string>
+#include "base/chunk_generator.hh"
#include "base/cprintf.hh" // csprintf
#include "base/trace.hh"
#include "dev/disk_image.hh"
@@ -42,11 +43,6 @@
#include "dev/ide_ctrl.hh"
#include "dev/tsunami.hh"
#include "dev/tsunami_pchip.hh"
-#include "mem/functional/physical.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 "sim/builder.hh"
#include "sim/sim_object.hh"
#include "sim/root.hh"
@@ -55,11 +51,11 @@
using namespace std;
using namespace TheISA;
-IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys,
+IdeDisk::IdeDisk(const string &name, DiskImage *img,
int id, Tick delay)
- : SimObject(name), ctrl(NULL), image(img), physmem(phys), diskDelay(delay),
- dmaTransferEvent(this), dmaReadWaitEvent(this),
- dmaWriteWaitEvent(this), dmaPrdReadEvent(this),
+ : SimObject(name), ctrl(NULL), image(img), diskDelay(delay),
+ dmaTransferEvent(this), dmaReadCG(NULL), dmaReadWaitEvent(this),
+ dmaWriteCG(NULL), dmaWriteWaitEvent(this), dmaPrdReadEvent(this),
dmaReadEvent(this), dmaWriteEvent(this)
{
// Reset the device state
@@ -139,7 +135,6 @@ IdeDisk::reset(int id)
memset(&cmdReg, 0, sizeof(CommandReg_t));
memset(&curPrd.entry, 0, sizeof(PrdEntry_t));
- dmaInterfaceBytes = 0;
curPrdAddr = 0;
curSector = 0;
cmdBytes = 0;
@@ -188,29 +183,6 @@ IdeDisk::pciToDma(Addr pciAddr)
panic("Access to unset controller!\n");
}
-uint32_t
-IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft)
-{
- uint32_t bytesInPage = 0;
-
- // First calculate how many bytes could be in the page
- if (bytesLeft > TheISA::PageBytes)
- bytesInPage = TheISA::PageBytes;
- else
- bytesInPage = bytesLeft;
-
- // Next, see if we have crossed a page boundary, and adjust
- Addr upperBound = curAddr + bytesInPage;
- Addr pageBound = TheISA::TruncPage(curAddr) + TheISA::PageBytes;
-
- assert(upperBound >= curAddr && "DMA read wraps around address space!\n");
-
- if (upperBound >= pageBound)
- bytesInPage = pageBound - curAddr;
-
- return bytesInPage;
-}
-
////
// Device registers read/write
////
@@ -263,6 +235,8 @@ IdeDisk::read(const Addr &offset, IdeRegType reg_type, uint8_t *data)
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);
@@ -324,6 +298,8 @@ IdeDisk::write(const Addr &offset, IdeRegType reg_type, const uint8_t *data)
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);
}
@@ -339,29 +315,17 @@ IdeDisk::doDmaTransfer()
panic("Inconsistent DMA transfer state: dmaState = %d devState = %d\n",
dmaState, devState);
- // first read the current PRD
- if (dmaInterface) {
- if (dmaInterface->busy()) {
- // reschedule after waiting period
- dmaTransferEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
- return;
- }
-
- dmaInterface->doDMA(Read, curPrdAddr, sizeof(PrdEntry_t), curTick,
- &dmaPrdReadEvent);
- } else {
- dmaPrdReadDone();
- }
+ if (ctrl->dmaPending()) {
+ dmaTransferEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
+ return;
+ } else
+ ctrl->dmaRead(curPrdAddr, sizeof(PrdEntry_t), &dmaPrdReadEvent,
+ (uint8_t*)&curPrd.entry);
}
void
IdeDisk::dmaPrdReadDone()
{
- // actually copy the PRD from physical memory
- memcpy((void *)&curPrd.entry,
- physmem->dma_addr(curPrdAddr, sizeof(PrdEntry_t)),
- sizeof(PrdEntry_t));
-
DPRINTF(IdeDisk,
"PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n",
curPrd.getBaseAddr(), pciToDma(curPrd.getBaseAddr()),
@@ -372,38 +336,49 @@ IdeDisk::dmaPrdReadDone()
curPrdAddr = curPrdAddr + sizeof(PrdEntry_t);
if (dmaRead)
- doDmaRead();
+ doDmaDataRead();
else
- doDmaWrite();
+ doDmaDataWrite();
}
void
-IdeDisk::doDmaRead()
+IdeDisk::doDmaDataRead()
{
/** @todo we need to figure out what the delay actually will be */
Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n",
diskDelay, totalDiskDelay);
- if (dmaInterface) {
- if (dmaInterface->busy()) {
- // reschedule after waiting period
- dmaReadWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
- return;
- }
- Addr dmaAddr = pciToDma(curPrd.getBaseAddr());
+ dmaReadWaitEvent.schedule(curTick + totalDiskDelay);
+}
- uint32_t bytesInPage = bytesInDmaPage(curPrd.getBaseAddr(),
- (uint32_t)curPrd.getByteCount());
- dmaInterfaceBytes = bytesInPage;
+void
+IdeDisk::doDmaRead()
+{
+
+ if (!dmaReadCG) {
+ // clear out the data buffer
+ memset(dataBuffer, 0, MAX_DMA_SIZE);
+ dmaReadCG = new ChunkGenerator(curPrd.getBaseAddr(),
+ curPrd.getByteCount(), TheISA::PageBytes);
- dmaInterface->doDMA(Read, dmaAddr, bytesInPage,
- curTick + totalDiskDelay, &dmaReadEvent);
+ }
+ if (ctrl->dmaPending()) {
+ panic("shouldn't be reentant??");
+ dmaReadWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
+ return;
+ } else if (!dmaReadCG->done()) {
+ assert(dmaReadCG->complete() < MAX_DMA_SIZE);
+ ctrl->dmaRead(pciToDma(dmaReadCG->addr()), dmaReadCG->size(),
+ &dmaReadWaitEvent, dataBuffer + dmaReadCG->complete());
+ dmaReadCG->next();
} else {
- // schedule dmaReadEvent with sectorDelay (dmaReadDone)
- dmaReadEvent.schedule(curTick + totalDiskDelay);
+ assert(dmaReadCG->done());
+ delete dmaReadCG;
+ dmaReadCG = NULL;
+ dmaReadDone();
}
}
@@ -411,63 +386,14 @@ void
IdeDisk::dmaReadDone()
{
- Addr curAddr = 0, dmaAddr = 0;
- uint32_t bytesWritten = 0, bytesInPage = 0, bytesLeft = 0;
-
- // continue to use the DMA interface until all pages are read
- if (dmaInterface && (dmaInterfaceBytes < curPrd.getByteCount())) {
- // see if the interface is busy
- if (dmaInterface->busy()) {
- // reschedule after waiting period
- dmaReadEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
- return;
- }
-
- uint32_t bytesLeft = curPrd.getByteCount() - dmaInterfaceBytes;
- curAddr = curPrd.getBaseAddr() + dmaInterfaceBytes;
- dmaAddr = pciToDma(curAddr);
-
- bytesInPage = bytesInDmaPage(curAddr, bytesLeft);
- dmaInterfaceBytes += bytesInPage;
-
- dmaInterface->doDMA(Read, dmaAddr, bytesInPage,
- curTick, &dmaReadEvent);
-
- return;
- }
-
- // set initial address
- curAddr = curPrd.getBaseAddr();
-
- // clear out the data buffer
- memset(dataBuffer, 0, MAX_DMA_SIZE);
+ uint32_t bytesWritten = 0;
- // read the data from memory via DMA into a data buffer
- while (bytesWritten < curPrd.getByteCount()) {
- if (cmdBytesLeft <= 0)
- panic("DMA data is larger than # of sectors specified\n");
-
- dmaAddr = pciToDma(curAddr);
-
- // calculate how many bytes are in the current page
- bytesLeft = curPrd.getByteCount() - bytesWritten;
- bytesInPage = bytesInDmaPage(curAddr, bytesLeft);
-
- // copy the data from memory into the data buffer
- memcpy((void *)(dataBuffer + bytesWritten),
- physmem->dma_addr(dmaAddr, bytesInPage),
- bytesInPage);
-
- curAddr += bytesInPage;
- bytesWritten += bytesInPage;
- cmdBytesLeft -= bytesInPage;
- }
// write the data to the disk image
- for (bytesWritten = 0;
- bytesWritten < curPrd.getByteCount();
+ for (bytesWritten = 0; bytesWritten < curPrd.getByteCount();
bytesWritten += SectorSize) {
+ cmdBytesLeft -= SectorSize;
writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten));
}
@@ -482,107 +408,55 @@ IdeDisk::dmaReadDone()
}
void
-IdeDisk::doDmaWrite()
+IdeDisk::doDmaDataWrite()
{
/** @todo we need to figure out what the delay actually will be */
Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
+ uint32_t bytesRead = 0;
DPRINTF(IdeDisk, "doDmaWrite, diskDelay: %d totalDiskDelay: %d\n",
diskDelay, totalDiskDelay);
- if (dmaInterface) {
- if (dmaInterface->busy()) {
- // reschedule after waiting period
- dmaWriteWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
- return;
- }
-
- Addr dmaAddr = pciToDma(curPrd.getBaseAddr());
+ memset(dataBuffer, 0, MAX_DMA_SIZE);
+ assert(cmdBytesLeft <= MAX_DMA_SIZE);
+ while (bytesRead < curPrd.getByteCount()) {
+ readDisk(curSector++, (uint8_t *)(dataBuffer + bytesRead));
+ bytesRead += SectorSize;
+ cmdBytesLeft -= SectorSize;
+ }
- uint32_t bytesInPage = bytesInDmaPage(curPrd.getBaseAddr(),
- (uint32_t)curPrd.getByteCount());
+ dmaWriteWaitEvent.schedule(curTick + totalDiskDelay);
+}
- dmaInterfaceBytes = bytesInPage;
+void
+IdeDisk::doDmaWrite()
+{
- dmaInterface->doDMA(WriteInvalidate, dmaAddr,
- bytesInPage, curTick + totalDiskDelay,
- &dmaWriteEvent);
+ if (!dmaWriteCG) {
+ // clear out the data buffer
+ dmaWriteCG = new ChunkGenerator(curPrd.getBaseAddr(),
+ curPrd.getByteCount(), TheISA::PageBytes);
+ }
+ if (ctrl->dmaPending()) {
+ panic("shouldn't be reentant??");
+ dmaWriteWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
+ return;
+ } else if (!dmaWriteCG->done()) {
+ assert(dmaWriteCG->complete() < MAX_DMA_SIZE);
+ ctrl->dmaWrite(pciToDma(dmaWriteCG->addr()), dmaWriteCG->size(),
+ &dmaWriteWaitEvent, dataBuffer + dmaWriteCG->complete());
+ dmaWriteCG->next();
} else {
- // schedule event with disk delay (dmaWriteDone)
- dmaWriteEvent.schedule(curTick + totalDiskDelay);
+ assert(dmaWriteCG->done());
+ delete dmaWriteCG;
+ dmaWriteCG = NULL;
+ dmaWriteDone();
}
}
void
IdeDisk::dmaWriteDone()
{
- Addr curAddr = 0, pageAddr = 0, dmaAddr = 0;
- uint32_t bytesRead = 0, bytesInPage = 0;
-
- // continue to use the DMA interface until all pages are read
- if (dmaInterface && (dmaInterfaceBytes < curPrd.getByteCount())) {
- // see if the interface is busy
- if (dmaInterface->busy()) {
- // reschedule after waiting period
- dmaWriteEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
- return;
- }
-
- uint32_t bytesLeft = curPrd.getByteCount() - dmaInterfaceBytes;
- curAddr = curPrd.getBaseAddr() + dmaInterfaceBytes;
- dmaAddr = pciToDma(curAddr);
-
- bytesInPage = bytesInDmaPage(curAddr, bytesLeft);
- dmaInterfaceBytes += bytesInPage;
-
- dmaInterface->doDMA(WriteInvalidate, dmaAddr,
- bytesInPage, curTick,
- &dmaWriteEvent);
-
- return;
- }
-
- // setup the initial page and DMA address
- curAddr = curPrd.getBaseAddr();
- pageAddr = TheISA::TruncPage(curAddr);
- dmaAddr = pciToDma(curAddr);
-
- // clear out the data buffer
- memset(dataBuffer, 0, MAX_DMA_SIZE);
-
- while (bytesRead < curPrd.getByteCount()) {
- // see if we have crossed into a new page
- if (pageAddr != TheISA::TruncPage(curAddr)) {
- // write the data to memory
- memcpy(physmem->dma_addr(dmaAddr, bytesInPage),
- (void *)(dataBuffer + (bytesRead - bytesInPage)),
- bytesInPage);
-
- // update the DMA address and page address
- pageAddr = TheISA::TruncPage(curAddr);
- dmaAddr = pciToDma(curAddr);
-
- bytesInPage = 0;
- }
-
- if (cmdBytesLeft <= 0)
- panic("DMA requested data is larger than # sectors specified\n");
-
- readDisk(curSector++, (uint8_t *)(dataBuffer + bytesRead));
-
- curAddr += SectorSize;
- bytesRead += SectorSize;
- bytesInPage += SectorSize;
- cmdBytesLeft -= SectorSize;
- }
-
- // write the last page worth read to memory
- if (bytesInPage != 0) {
- memcpy(physmem->dma_addr(dmaAddr, bytesInPage),
- (void *)(dataBuffer + (bytesRead - bytesInPage)),
- bytesInPage);
- }
-
// check for the EOT
if (curPrd.getEOT()) {
assert(cmdBytesLeft == 0);
@@ -1138,13 +1012,13 @@ IdeDisk::serialize(ostream &os)
SERIALIZE_SCALAR(curPrd.entry.endOfTable);
SERIALIZE_SCALAR(curPrdAddr);
+ /** @todo need to serialized chunk generator stuff!! */
// Serialize current transfer related information
SERIALIZE_SCALAR(cmdBytesLeft);
SERIALIZE_SCALAR(cmdBytes);
SERIALIZE_SCALAR(drqBytesLeft);
SERIALIZE_SCALAR(curSector);
SERIALIZE_SCALAR(dmaRead);
- SERIALIZE_SCALAR(dmaInterfaceBytes);
SERIALIZE_SCALAR(intrPending);
SERIALIZE_ENUM(devState);
SERIALIZE_ENUM(dmaState);
@@ -1190,13 +1064,13 @@ IdeDisk::unserialize(Checkpoint *cp, const string &section)
UNSERIALIZE_SCALAR(curPrd.entry.endOfTable);
UNSERIALIZE_SCALAR(curPrdAddr);
+ /** @todo need to serialized chunk generator stuff!! */
// Unserialize current transfer related information
UNSERIALIZE_SCALAR(cmdBytes);
UNSERIALIZE_SCALAR(cmdBytesLeft);
UNSERIALIZE_SCALAR(drqBytesLeft);
UNSERIALIZE_SCALAR(curSector);
UNSERIALIZE_SCALAR(dmaRead);
- UNSERIALIZE_SCALAR(dmaInterfaceBytes);
UNSERIALIZE_SCALAR(intrPending);
UNSERIALIZE_ENUM(devState);
UNSERIALIZE_ENUM(dmaState);
@@ -1210,7 +1084,6 @@ static const char *DriveID_strings[] = { "master", "slave" };
BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeDisk)
SimObjectParam<DiskImage *> image;
- SimObjectParam<PhysicalMemory *> physmem;
SimpleEnumParam<DriveID> driveID;
Param<int> delay;
@@ -1219,7 +1092,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(IdeDisk)
BEGIN_INIT_SIM_OBJECT_PARAMS(IdeDisk)
INIT_PARAM(image, "Disk image"),
- INIT_PARAM(physmem, "Physical memory"),
INIT_ENUM_PARAM(driveID, "Drive ID (0=master 1=slave)", DriveID_strings),
INIT_PARAM_DFLT(delay, "Fixed disk delay in microseconds", 1)
@@ -1228,7 +1100,7 @@ END_INIT_SIM_OBJECT_PARAMS(IdeDisk)
CREATE_SIM_OBJECT(IdeDisk)
{
- return new IdeDisk(getInstanceName(), image, physmem, driveID, delay);
+ return new IdeDisk(getInstanceName(), image, driveID, delay);
}
REGISTER_SIM_OBJECT("IdeDisk", IdeDisk)
diff --git a/dev/ide_disk.hh b/dev/ide_disk.hh
index a656ca464..3d67abece 100644
--- a/dev/ide_disk.hh
+++ b/dev/ide_disk.hh
@@ -42,7 +42,7 @@
#define DMA_BACKOFF_PERIOD 200
-#define MAX_DMA_SIZE (65536) // 64K
+#define MAX_DMA_SIZE (131072) // 128K
#define MAX_MULTSECT (128)
#define PRD_BASE_MASK 0xfffffffe
@@ -190,12 +190,8 @@ class IdeDisk : public SimObject
protected:
/** The IDE controller for this disk. */
IdeController *ctrl;
- /** The DMA interface to use for transfers */
- DMAInterface<Bus> *dmaInterface;
/** The image that contains the data of this disk. */
DiskImage *image;
- /** Pointer to physical memory for DMA transfers */
- PhysicalMemory *physmem;
protected:
/** The disk delay in microseconds. */
@@ -230,8 +226,6 @@ class IdeDisk : public SimObject
uint32_t curPrdAddr;
/** PRD entry */
PrdTableEntry curPrd;
- /** Number of bytes transfered by DMA interface for current transfer */
- uint32_t dmaInterfaceBytes;
/** Device ID (master=0/slave=1) */
int devID;
/** Interrupt pending */
@@ -242,12 +236,10 @@ class IdeDisk : public SimObject
* Create and initialize this Disk.
* @param name The name of this disk.
* @param img The disk image of this disk.
- * @param phys Pointer to physical memory
* @param id The disk ID (master=0/slave=1)
* @param disk_delay The disk delay in milliseconds
*/
- IdeDisk(const std::string &name, DiskImage *img, PhysicalMemory *phys,
- int id, Tick disk_delay);
+ IdeDisk(const std::string &name, DiskImage *img, int id, Tick disk_delay);
/**
* Delete the data buffer.
@@ -263,10 +255,9 @@ class IdeDisk : public SimObject
* Set the controller for this device
* @param c The IDE controller
*/
- void setController(IdeController *c, DMAInterface<Bus> *dmaIntr) {
+ void setController(IdeController *c) {
if (ctrl) panic("Cannot change the controller once set!\n");
ctrl = c;
- dmaInterface = dmaIntr;
}
// Device register read/write
@@ -289,11 +280,17 @@ class IdeDisk : public SimObject
friend class EventWrapper<IdeDisk, &IdeDisk::doDmaTransfer>;
EventWrapper<IdeDisk, &IdeDisk::doDmaTransfer> dmaTransferEvent;
+ void doDmaDataRead();
+
void doDmaRead();
+ ChunkGenerator *dmaReadCG;
friend class EventWrapper<IdeDisk, &IdeDisk::doDmaRead>;
EventWrapper<IdeDisk, &IdeDisk::doDmaRead> dmaReadWaitEvent;
+ void doDmaDataWrite();
+
void doDmaWrite();
+ ChunkGenerator *dmaWriteCG;
friend class EventWrapper<IdeDisk, &IdeDisk::doDmaWrite>;
EventWrapper<IdeDisk, &IdeDisk::doDmaWrite> dmaWriteWaitEvent;
@@ -339,8 +336,6 @@ class IdeDisk : public SimObject
inline Addr pciToDma(Addr pciAddr);
- uint32_t bytesInDmaPage(Addr curAddr, uint32_t bytesLeft);
-
/**
* Serialize this object to the given output stream.
* @param os The stream to serialize to.
diff --git a/dev/io_device.cc b/dev/io_device.cc
index a2e5a8a0d..42b3c382f 100644
--- a/dev/io_device.cc
+++ b/dev/io_device.cc
@@ -105,23 +105,24 @@ BasicPioDevice::addressRanges(AddrRangeList &range_list)
}
-DmaPort::DmaPort(DmaDevice *dev)
- : device(dev)
+DmaPort::DmaPort(DmaDevice *dev, Platform *p)
+ : device(dev), platform(p), pendingCount(0)
{ }
bool
DmaPort::recvTiming(Packet &pkt)
{
- completionEvent->schedule(curTick+1);
- completionEvent = NULL;
+ if (pkt.senderState) {
+ DmaReqState *state;
+ state = (DmaReqState*)pkt.senderState;
+ state->completionEvent->schedule(pkt.time - pkt.req->getTime());
+ }
return Success;
}
DmaDevice::DmaDevice(Params *p)
- : PioDevice(p)
-{
- dmaPort = new DmaPort(this);
-}
+ : PioDevice(p), dmaPort(NULL)
+{ }
void
DmaPort::SendEvent::process()
@@ -140,8 +141,8 @@ DmaPort::recvRetry()
return pkt;
}
void
-DmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size,
- Event *event, uint8_t *data)
+DmaPort::dmaAction(Command cmd, Addr addr, int size, Event *event,
+ uint8_t *data)
{
assert(event);
@@ -161,8 +162,6 @@ DmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size,
// baseReq.nicReq = true;
baseReq.setTime(curTick);
- completionEvent = event;
-
for (ChunkGenerator gen(addr, size, peerBlockSize());
!gen.done(); gen.next()) {
Packet *pkt = new Packet(basePkt);
@@ -173,16 +172,28 @@ DmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size,
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;
-
- sendDma(*pkt);
+ // Set the last bit of the dma as the final packet for this dma
+ // and set it's completion event.
+ if (prevSize == size) {
+ DmaReqState *state = new DmaReqState(event, true);
+
+ pkt->senderState = (void*)state;
+ }
+ assert(pendingCount >= 0);
+ pendingCount++;
+ 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
@@ -193,9 +204,16 @@ DmaPort::sendDma(Packet &pkt)
if (sendTiming(pkt) == Failure)
transmitList.push_back(&packet);
} else if (state == Atomic) {*/
- sendAtomic(pkt);
- completionEvent->schedule(pkt.time - pkt.req->getTime());
- completionEvent = NULL;
+ sendAtomic(*pkt);
+ if (pkt->senderState) {
+ DmaReqState *state = (DmaReqState*)pkt->senderState;
+ state->completionEvent->schedule(curTick + (pkt->time - pkt->req->getTime()) +1);
+ }
+ pendingCount--;
+ assert(pendingCount >= 0);
+ delete pkt->req;
+ delete pkt;
+
/* } else if (state == Functional) {
sendFunctional(pkt);
// Is this correct???
diff --git a/dev/io_device.hh b/dev/io_device.hh
index 5379a664c..bc0160c46 100644
--- a/dev/io_device.hh
+++ b/dev/io_device.hh
@@ -113,13 +113,28 @@ class PioPort : public Port
friend class PioPort::SendEvent;
};
+
+struct DmaReqState
+{
+ Event *completionEvent;
+ bool final;
+ DmaReqState(Event *ce, bool f)
+ : completionEvent(ce), final(f)
+ {}
+};
+
class DmaPort : public Port
{
protected:
- PioDevice *device;
+ DmaDevice *device;
std::list<Packet*> transmitList;
- Event *completionEvent;
+ /** The platform that device/port are in. This is used to select which mode
+ * we are currently operating in. */
+ Platform *platform;
+
+ /** Number of outstanding packets the dma port has. */
+ int pendingCount;
virtual bool recvTiming(Packet &pkt);
virtual Tick recvAtomic(Packet &pkt)
@@ -152,13 +167,15 @@ class DmaPort : public Port
friend class DmaPort;
};
- void dmaAction(Command cmd, DmaPort port, Addr addr, int size,
- Event *event, uint8_t *data = NULL);
-
void sendDma(Packet &pkt);
public:
- DmaPort(DmaDevice *dev);
+ DmaPort(DmaDevice *dev, Platform *p);
+
+ void dmaAction(Command cmd, Addr addr, int size, Event *event,
+ uint8_t *data = NULL);
+
+ bool dmaPending() { return pendingCount > 0; }
friend class DmaPort::SendEvent;
@@ -286,13 +303,27 @@ class DmaDevice : public PioDevice
DmaDevice(Params *p);
virtual ~DmaDevice();
+ void dmaWrite(Addr addr, int size, Event *event, uint8_t *data)
+ { dmaPort->dmaAction(Write, addr, size, event, data) ; }
+
+ void dmaRead(Addr addr, int size, Event *event, uint8_t *data = NULL)
+ { dmaPort->dmaAction(Read, addr, size, event, data); }
+
+ bool dmaPending() { return dmaPort->dmaPending(); }
+
virtual Port *getPort(const std::string &if_name)
{
- if (if_name == "pio")
+ if (if_name == "pio") {
+ if (pioPort != NULL)
+ panic("pio port already connected to.");
+ pioPort = new PioPort(this, params()->platform);
return pioPort;
- else if (if_name == "dma")
+ } else if (if_name == "dma") {
+ if (dmaPort != NULL)
+ panic("dma port already connected to.");
+ dmaPort = new DmaPort(this, params()->platform);
return dmaPort;
- else
+ } else
return NULL;
}
diff --git a/dev/isa_fake.cc b/dev/isa_fake.cc
index 1ed355499..8060d1a7c 100644
--- a/dev/isa_fake.cc
+++ b/dev/isa_fake.cc
@@ -58,47 +58,17 @@ IsaFake::read(Packet &pkt)
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");
diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc
index f7e67811c..02c9bbca4 100644
--- a/dev/ns_gige.cc
+++ b/dev/ns_gige.cc
@@ -40,17 +40,12 @@
#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[] =
{
@@ -108,29 +103,9 @@ NSGigE::NSGigE(Params *p)
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;
@@ -484,30 +459,18 @@ NSGigE::regStats()
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
@@ -517,39 +480,6 @@ NSGigE::writeConfig(int offset, int size, const uint8_t* data)
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;
}
}
@@ -558,15 +488,18 @@ NSGigE::writeConfig(int offset, int size, const uint8_t* data)
* 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
@@ -574,240 +507,246 @@ NSGigE::read(MemReqPtr &req, uint8_t *data)
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 &reg = *(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 &reg = *(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 &reg = *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);
@@ -1193,8 +1132,8 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
} else {
panic("Invalid Request Size");
}
-
- return NoFault;
+ pkt.result = Success;
+ return pioDelay;
}
void
@@ -1444,42 +1383,17 @@ NSGigE::regsReset()
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;
}
@@ -1487,7 +1401,11 @@ void
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)
@@ -1496,42 +1414,16 @@ NSGigE::rxDmaReadDone()
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;
}
@@ -1539,7 +1431,11 @@ void
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)
@@ -1936,42 +1832,17 @@ NSGigE::transmit()
}
}
-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;
}
@@ -1979,7 +1850,11 @@ void
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)
@@ -1988,42 +1863,16 @@ NSGigE::txDmaReadDone()
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;
}
@@ -2031,7 +1880,11 @@ void
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)
@@ -2148,7 +2001,7 @@ NSGigE::txKick()
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;
}
@@ -2474,7 +2327,7 @@ NSGigE::transferDone()
}
bool
-NSGigE::rxFilter(const PacketPtr &packet)
+NSGigE::rxFilter(const EthPacketPtr &packet)
{
EthPtr eth = packet;
bool drop = true;
@@ -2517,7 +2370,7 @@ NSGigE::rxFilter(const PacketPtr &packet)
}
bool
-NSGigE::recvPacket(PacketPtr packet)
+NSGigE::recvPacket(EthPacketPtr packet)
{
rxBytes += packet->length;
rxPackets++;
@@ -2577,14 +2430,7 @@ NSGigE::serialize(ostream &os)
/*
* 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
@@ -2805,7 +2651,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
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);
@@ -2817,7 +2663,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
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);
@@ -2926,23 +2772,6 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
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)
@@ -2977,22 +2806,16 @@ REGISTER_SIM_OBJECT("NSGigEInt", 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;
@@ -3000,7 +2823,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
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;
@@ -3018,22 +2840,16 @@ END_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
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"),
@@ -3041,7 +2857,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
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"),
@@ -3063,22 +2878,16 @@ CREATE_SIM_OBJECT(NSGigE)
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;
@@ -3086,7 +2895,7 @@ CREATE_SIM_OBJECT(NSGigE)
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;
diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh
index 59c55056e..7bb422287 100644
--- a/dev/ns_gige.hh
+++ b/dev/ns_gige.hh
@@ -42,7 +42,6 @@
#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
@@ -111,10 +110,7 @@ struct dp_rom {
};
class NSGigEInt;
-class PhysicalMemory;
-class BaseInterface;
-class HierParams;
-class Bus;
+class Packet;
class PciConfigAll;
/**
@@ -165,10 +161,6 @@ class NSGigE : public PciDev
eepromRead
};
- private:
- Addr addr;
- static const Addr size = sizeof(dp_regs);
-
protected:
/** device register file */
dp_regs regs;
@@ -187,8 +179,8 @@ class NSGigE : public PciDev
PacketFifo rxFifo;
/** various helper vars */
- PacketPtr txPacket;
- PacketPtr rxPacket;
+ EthPacketPtr txPacket;
+ EthPacketPtr rxPacket;
uint8_t *txPacketBufPtr;
uint8_t *rxPacketBufPtr;
uint32_t txXferLen;
@@ -258,16 +250,12 @@ class NSGigE : public PciDev
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>;
@@ -331,7 +319,7 @@ class NSGigE : public PciDev
* receive address filter
*/
bool rxFilterEnable;
- bool rxFilter(const PacketPtr &packet);
+ bool rxFilter(const EthPacketPtr &packet);
bool acceptBroadcast;
bool acceptMulticast;
bool acceptUnicast;
@@ -339,8 +327,6 @@ class NSGigE : public PciDev
bool acceptArp;
bool multicastHashEnable;
- PhysicalMemory *physmem;
-
/**
* Interrupt management
*/
@@ -363,16 +349,10 @@ class NSGigE : public PciDev
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;
@@ -393,16 +373,15 @@ class NSGigE : public PciDev
~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; }
@@ -463,9 +442,6 @@ class NSGigE : public PciDev
Stats::Formula coalescedTotal;
Stats::Scalar<> postedInterrupts;
Stats::Scalar<> droppedPackets;
-
- public:
- Tick cacheAccess(MemReqPtr &req);
};
/*
@@ -480,7 +456,7 @@ class NSGigEInt : public EtherInt
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(); }
};
diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc
index 86a505b9a..c3597c486 100644
--- a/dev/pciconfigall.cc
+++ b/dev/pciconfigall.cc
@@ -37,7 +37,7 @@
#include "base/trace.hh"
#include "dev/pciconfigall.hh"
-//#include "dev/pcidev.hh"
+#include "dev/pcidev.hh"
#include "dev/pcireg.h"
#include "dev/platform.hh"
#include "mem/packet.hh"
@@ -68,7 +68,7 @@ PciConfigAll::PciConfigAll(Params *p)
void
PciConfigAll::startup()
{
-/* bitset<256> intLines;
+ bitset<256> intLines;
PciDev *tempDev;
uint8_t intline;
@@ -85,7 +85,7 @@ PciConfigAll::startup()
} // devices != NULL
} // PCI_FUNC
} // PCI_DEV
- */
+
}
Tick
@@ -97,65 +97,32 @@ PciConfigAll::read(Packet &pkt)
Addr daddr = pkt.addr - pioAddr;
int device = (daddr >> 11) & 0x1F;
int func = (daddr >> 8) & 0x7;
- //int reg = daddr & 0xFF;
+ 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, req.size, 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, req.size, 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, req.size, data8);
+ devices[device][func]->readConfig(reg, pkt.getPtr<uint8_t>());
break;
default:
panic("invalid access size(?) for PCI configspace!\n");
@@ -177,16 +144,27 @@ PciConfigAll::write(Packet &pkt)
int device = (daddr >> 11) & 0x1F;
int func = (daddr >> 8) & 0x7;
-// int reg = daddr & 0xFF;
+ int reg = daddr & 0xFF;
if (devices[device][func] == NULL)
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);
-
-// devices[device][func]->writeConfig(reg, req->size, data);
+ pkt.addr, pkt.size, pkt.get<uint32_t>());
+ switch (pkt.size) {
+ case sizeof(uint8_t):
+ devices[device][func]->writeConfig(reg, pkt.get<uint8_t>());
+ break;
+ case sizeof(uint16_t):
+ devices[device][func]->writeConfig(reg, pkt.get<uint16_t>());
+ break;
+ case sizeof(uint32_t):
+ devices[device][func]->writeConfig(reg, pkt.get<uint32_t>());
+ break;
+ default:
+ panic("invalid pci config write size\n");
+ }
return pioDelay;
}
diff --git a/dev/pciconfigall.hh b/dev/pciconfigall.hh
index b2034594c..2393b445e 100644
--- a/dev/pciconfigall.hh
+++ b/dev/pciconfigall.hh
@@ -54,8 +54,6 @@ class PciDev;
class PciConfigAll : public BasicPioDevice
{
private:
- static const Addr size = 0xffffff;
-
/**
* Pointers to all the devices that are registered with this
* particular config space.
diff --git a/dev/pcidev.cc b/dev/pcidev.cc
index a05ee3803..c40ef62e4 100644
--- a/dev/pcidev.cc
+++ b/dev/pcidev.cc
@@ -39,20 +39,20 @@
#include "base/misc.hh"
#include "base/str.hh" // for to_number
#include "base/trace.hh"
-#include "dev/pcidev.hh"
#include "dev/pciconfigall.hh"
-#include "mem/bus/bus.hh"
-#include "mem/functional/memory_control.hh"
+#include "dev/pcidev.hh"
+#include "dev/tsunamireg.h"
+#include "mem/packet.hh"
#include "sim/builder.hh"
+#include "sim/byteswap.hh"
#include "sim/param.hh"
#include "sim/root.hh"
-#include "dev/tsunamireg.h"
using namespace std;
PciDev::PciDev(Params *p)
- : DmaDevice(p->name, p->plat), _params(p), plat(p->plat),
- configData(p->configData)
+ : DmaDevice(p), plat(p->platform), configData(p->configData),
+ pioDelay(p->pio_delay)
{
// copy the config data from the PciConfigData object
if (configData) {
@@ -70,214 +70,180 @@ PciDev::PciDev(Params *p)
p->configSpace->registerDevice(p->deviceNum, p->functionNum, this);
}
-Fault
-PciDev::read(MemReqPtr &req, uint8_t *data)
-{ return NoFault; }
-
-Fault
-PciDev::write(MemReqPtr &req, const uint8_t *data)
-{ return NoFault; }
-
-Fault
-PciDev::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data)
-{ panic("not implemented"); }
-
-Fault
-PciDev::readBar1(MemReqPtr &req, Addr daddr, uint8_t *data)
-{ panic("not implemented"); }
+void
+PciDev::readConfig(int offset, uint8_t *data)
+{
+ if (offset >= PCI_DEVICE_SPECIFIC)
+ panic("Device specific PCI config space not implemented!\n");
-Fault
-PciDev::readBar2(MemReqPtr &req, Addr daddr, uint8_t *data)
-{ panic("not implemented"); }
+ *data = config.data[offset];
-Fault
-PciDev::readBar3(MemReqPtr &req, Addr daddr, uint8_t *data)
-{ panic("not implemented"); }
+ DPRINTF(PCIDEV,
+ "read device: %#x function: %#x register: %#x 1 bytes: data: %#x\n",
+ params()->deviceNum, params()->functionNum, offset, *data);
+}
-Fault
-PciDev::readBar4(MemReqPtr &req, Addr daddr, uint8_t *data)
-{ panic("not implemented"); }
+void
+PciDev::addressRanges(AddrRangeList &range_list)
+{
+ int x = 0;
+ range_list.clear();
+ for (x = 0; x < 6; x++)
+ if (BARAddrs[x] != 0)
+ range_list.push_back(RangeSize(BARAddrs[x],BARSize[x]));
+}
-Fault
-PciDev::readBar5(MemReqPtr &req, Addr daddr, uint8_t *data)
-{ panic("not implemented"); }
+void
+PciDev::readConfig(int offset, uint16_t *data)
+{
+ if (offset >= PCI_DEVICE_SPECIFIC)
+ panic("Device specific PCI config space not implemented!\n");
-Fault
-PciDev::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
-{ panic("not implemented"); }
+ *data = *(uint16_t*)&config.data[offset];
-Fault
-PciDev::writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data)
-{ panic("not implemented"); }
+ DPRINTF(PCIDEV,
+ "read device: %#x function: %#x register: %#x 2 bytes: data: %#x\n",
+ params()->deviceNum, params()->functionNum, offset, *data);
+}
-Fault
-PciDev::writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data)
-{ panic("not implemented"); }
+void
+PciDev::readConfig(int offset, uint32_t *data)
+{
+ if (offset >= PCI_DEVICE_SPECIFIC)
+ panic("Device specific PCI config space not implemented!\n");
-Fault
-PciDev::writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data)
-{ panic("not implemented"); }
+ *data = *(uint32_t*)&config.data[offset];
-Fault
-PciDev::writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data)
-{ panic("not implemented"); }
+ DPRINTF(PCIDEV,
+ "read device: %#x function: %#x register: %#x 4 bytes: data: %#x\n",
+ params()->deviceNum, params()->functionNum, offset, *data);
+}
-Fault
-PciDev::writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data)
-{ panic("not implemented"); }
void
-PciDev::readConfig(int offset, int size, uint8_t *data)
+PciDev::writeConfig(int offset, const uint8_t data)
{
if (offset >= PCI_DEVICE_SPECIFIC)
panic("Device specific PCI config space not implemented!\n");
- switch(size) {
- case sizeof(uint8_t):
- *data = config.data[offset];
- break;
- case sizeof(uint16_t):
- *(uint16_t*)data = *(uint16_t*)&config.data[offset];
+ DPRINTF(PCIDEV,
+ "write device: %#x function: %#x reg: %#x size: 1 data: %#x\n",
+ params()->deviceNum, params()->functionNum, offset, data);
+
+ switch (offset) {
+ case PCI0_INTERRUPT_LINE:
+ config.interruptLine = data;
+ case PCI_CACHE_LINE_SIZE:
+ config.cacheLineSize = data;
+ case PCI_LATENCY_TIMER:
+ config.latencyTimer = data;
break;
- case sizeof(uint32_t):
- *(uint32_t*)data = *(uint32_t*)&config.data[offset];
+ /* Do nothing for these read-only registers */
+ case PCI0_INTERRUPT_PIN:
+ case PCI0_MINIMUM_GRANT:
+ case PCI0_MAXIMUM_LATENCY:
+ case PCI_CLASS_CODE:
+ case PCI_REVISION_ID:
break;
default:
- panic("Invalid PCI configuration read size!\n");
+ panic("writing to a read only register");
}
-
- DPRINTF(PCIDEV,
- "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n",
- params()->deviceNum, params()->functionNum, offset, size,
- *(uint32_t*)data);
}
void
-PciDev::writeConfig(int offset, int size, const uint8_t *data)
+PciDev::writeConfig(int offset, const uint16_t data)
{
if (offset >= PCI_DEVICE_SPECIFIC)
panic("Device specific PCI config space not implemented!\n");
- uint8_t &data8 = *(uint8_t*)data;
- uint16_t &data16 = *(uint16_t*)data;
- uint32_t &data32 = *(uint32_t*)data;
-
DPRINTF(PCIDEV,
- "write device: %#x function: %#x reg: %#x size: %d data: %#x\n",
- params()->deviceNum, params()->functionNum, offset, size, data32);
-
- switch (size) {
- case sizeof(uint8_t): // 1-byte access
- switch (offset) {
- case PCI0_INTERRUPT_LINE:
- config.interruptLine = data8;
- case PCI_CACHE_LINE_SIZE:
- config.cacheLineSize = data8;
- case PCI_LATENCY_TIMER:
- config.latencyTimer = data8;
- break;
- /* Do nothing for these read-only registers */
- case PCI0_INTERRUPT_PIN:
- case PCI0_MINIMUM_GRANT:
- case PCI0_MAXIMUM_LATENCY:
- case PCI_CLASS_CODE:
- case PCI_REVISION_ID:
- break;
- default:
- panic("writing to a read only register");
- }
+ "write device: %#x function: %#x reg: %#x size: 2 data: %#x\n",
+ params()->deviceNum, params()->functionNum, offset, data);
+
+ switch (offset) {
+ case PCI_COMMAND:
+ config.command = data;
+ case PCI_STATUS:
+ config.status = data;
+ case PCI_CACHE_LINE_SIZE:
+ config.cacheLineSize = data;
break;
+ default:
+ panic("writing to a read only register");
+ }
+}
- case sizeof(uint16_t): // 2-byte access
- switch (offset) {
- case PCI_COMMAND:
- config.command = data16;
- case PCI_STATUS:
- config.status = data16;
- case PCI_CACHE_LINE_SIZE:
- config.cacheLineSize = data16;
- break;
- default:
- panic("writing to a read only register");
- }
- break;
- case sizeof(uint32_t): // 4-byte access
- switch (offset) {
- case PCI0_BASE_ADDR0:
- case PCI0_BASE_ADDR1:
- case PCI0_BASE_ADDR2:
- case PCI0_BASE_ADDR3:
- case PCI0_BASE_ADDR4:
- case PCI0_BASE_ADDR5:
-
- uint32_t barnum, bar_mask;
- Addr base_addr, base_size, space_base;
-
- barnum = BAR_NUMBER(offset);
-
- if (BAR_IO_SPACE(letoh(config.baseAddr[barnum]))) {
- bar_mask = BAR_IO_MASK;
- space_base = TSUNAMI_PCI0_IO;
- } else {
- bar_mask = BAR_MEM_MASK;
- space_base = TSUNAMI_PCI0_MEMORY;
- }
+void
+PciDev::writeConfig(int offset, const uint32_t data)
+{
+ if (offset >= PCI_DEVICE_SPECIFIC)
+ panic("Device specific PCI config space not implemented!\n");
- // Writing 0xffffffff to a BAR tells the card to set the
- // value of the bar to size of memory it needs
- if (letoh(data32) == 0xffffffff) {
- // This is I/O Space, bottom two bits are read only
+ DPRINTF(PCIDEV,
+ "write device: %#x function: %#x reg: %#x size: 4 data: %#x\n",
+ params()->deviceNum, params()->functionNum, offset, data);
+
+ switch (offset) {
+ case PCI0_BASE_ADDR0:
+ case PCI0_BASE_ADDR1:
+ case PCI0_BASE_ADDR2:
+ case PCI0_BASE_ADDR3:
+ case PCI0_BASE_ADDR4:
+ case PCI0_BASE_ADDR5:
+
+ uint32_t barnum, bar_mask;
+ Addr base_addr, base_size, space_base;
+
+ barnum = BAR_NUMBER(offset);
+
+ if (BAR_IO_SPACE(letoh(config.baseAddr[barnum]))) {
+ bar_mask = BAR_IO_MASK;
+ space_base = TSUNAMI_PCI0_IO;
+ } else {
+ bar_mask = BAR_MEM_MASK;
+ space_base = TSUNAMI_PCI0_MEMORY;
+ }
- config.baseAddr[barnum] = letoh(
- (~(BARSize[barnum] - 1) & ~bar_mask) |
- (letoh(config.baseAddr[barnum]) & bar_mask));
- } else {
- MemoryController *mmu = params()->mmu;
+ // Writing 0xffffffff to a BAR tells the card to set the
+ // value of the bar to size of memory it needs
+ if (letoh(data) == 0xffffffff) {
+ // This is I/O Space, bottom two bits are read only
- config.baseAddr[barnum] = letoh(
- (letoh(data32) & ~bar_mask) |
+ config.baseAddr[barnum] = letoh(
+ (~(BARSize[barnum] - 1) & ~bar_mask) |
(letoh(config.baseAddr[barnum]) & bar_mask));
+ } else {
+ config.baseAddr[barnum] = letoh(
+ (letoh(data) & ~bar_mask) |
+ (letoh(config.baseAddr[barnum]) & bar_mask));
+
+ if (letoh(config.baseAddr[barnum]) & ~bar_mask) {
+ base_addr = (letoh(data) & ~bar_mask) + space_base;
+ base_size = BARSize[barnum];
+ BARAddrs[barnum] = base_addr;
- if (letoh(config.baseAddr[barnum]) & ~bar_mask) {
- base_addr = (letoh(data32) & ~bar_mask) + space_base;
- base_size = BARSize[barnum];
-
- // It's never been set
- if (BARAddrs[barnum] == 0)
- mmu->add_child((FunctionalMemory *)this,
- RangeSize(base_addr, base_size));
- else
- mmu->update_child((FunctionalMemory *)this,
- RangeSize(BARAddrs[barnum], base_size),
- RangeSize(base_addr, base_size));
-
- BARAddrs[barnum] = base_addr;
- }
+ pioPort->sendStatusChange(Port::RangeChange);
}
- break;
-
- case PCI0_ROM_BASE_ADDR:
- if (letoh(data32) == 0xfffffffe)
- config.expansionROM = htole((uint32_t)0xffffffff);
- else
- config.expansionROM = data32;
- break;
-
- case PCI_COMMAND:
- // This could also clear some of the error bits in the Status
- // register. However they should never get set, so lets ignore
- // it for now
- config.command = data16;
- break;
-
- default:
- DPRINTF(PCIDEV, "Writing to a read only register");
}
break;
+ case PCI0_ROM_BASE_ADDR:
+ if (letoh(data) == 0xfffffffe)
+ config.expansionROM = htole((uint32_t)0xffffffff);
+ else
+ config.expansionROM = data;
+ break;
+
+ case PCI_COMMAND:
+ // This could also clear some of the error bits in the Status
+ // register. However they should never get set, so lets ignore
+ // it for now
+ config.command = data;
+ break;
+
default:
- panic("invalid access size");
+ DPRINTF(PCIDEV, "Writing to a read only register");
}
}
@@ -296,12 +262,6 @@ PciDev::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0]));
UNSERIALIZE_ARRAY(config.data,
sizeof(config.data) / sizeof(config.data[0]));
-
- // Add the MMU mappings for the BARs
- for (int i=0; i < 6; i++) {
- if (BARAddrs[i] != 0)
- params()->mmu->add_child(this, RangeSize(BARAddrs[i], BARSize[i]));
- }
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
diff --git a/dev/pcidev.hh b/dev/pcidev.hh
index bdfc6b932..fc4773908 100644
--- a/dev/pcidev.hh
+++ b/dev/pcidev.hh
@@ -44,7 +44,6 @@
#define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2);
class PciConfigAll;
-class MemoryController;
/**
@@ -85,12 +84,8 @@ class PciConfigData : public SimObject
class PciDev : public DmaDevice
{
public:
- struct Params
+ struct Params : public ::PioDevice::Params
{
- std::string name;
- Platform *plat;
- MemoryController *mmu;
-
/**
* A pointer to the configspace all object that calls us when
* a read comes to this particular device/function.
@@ -111,13 +106,13 @@ class PciDev : public DmaDevice
/** The function number */
uint32_t functionNum;
- };
- protected:
- Params *_params;
+ /** The latency for pio accesses. */
+ Tick pio_delay;
+ };
public:
- const Params *params() const { return _params; }
+ const Params *params() const { return (const Params *)_params; }
protected:
/** The current config space. Unlike the PciConfigData this is
@@ -164,6 +159,7 @@ class PciDev : public DmaDevice
protected:
Platform *plat;
PciConfigData *configData;
+ Tick pioDelay;
public:
Addr pciToDma(Addr pciAddr) const
@@ -181,7 +177,11 @@ class PciDev : public DmaDevice
interruptLine()
{ return configData->config.interruptLine; }
- public:
+ /** return the address ranges that this device responds to.
+ * @params range_list range list to populate with ranges
+ */
+ void addressRanges(AddrRangeList &range_list);
+
/**
* Constructor for PCI Dev. This function copies data from the
* config file object PCIConfigData and registers the device with
@@ -189,39 +189,6 @@ class PciDev : public DmaDevice
*/
PciDev(Params *params);
- virtual Fault read(MemReqPtr &req, uint8_t *data);
- virtual Fault write(MemReqPtr &req, const uint8_t *data);
-
- public:
- /**
- * Implement the read/write as BAR accesses
- */
- Fault readBar(MemReqPtr &req, uint8_t *data);
- Fault writeBar(MemReqPtr &req, const uint8_t *data);
-
- public:
- /**
- * Read from a specific BAR
- */
- virtual Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data);
- virtual Fault readBar1(MemReqPtr &req, Addr daddr, uint8_t *data);
- virtual Fault readBar2(MemReqPtr &req, Addr daddr, uint8_t *data);
- virtual Fault readBar3(MemReqPtr &req, Addr daddr, uint8_t *data);
- virtual Fault readBar4(MemReqPtr &req, Addr daddr, uint8_t *data);
- virtual Fault readBar5(MemReqPtr &req, Addr daddr, uint8_t *data);
-
- public:
- /**
- * Write to a specific BAR
- */
- virtual Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data);
- virtual Fault writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data);
- virtual Fault writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data);
- virtual Fault writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data);
- virtual Fault writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data);
- virtual Fault writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data);
-
- public:
/**
* Write to the PCI config space data that is stored locally. This may be
* overridden by the device but at some point it will eventually call this
@@ -230,7 +197,9 @@ class PciDev : public DmaDevice
* @param size the size of the write
* @param data the data to write
*/
- virtual void writeConfig(int offset, int size, const uint8_t* data);
+ virtual void writeConfig(int offset, const uint8_t data);
+ virtual void writeConfig(int offset, const uint16_t data);
+ virtual void writeConfig(int offset, const uint32_t data);
/**
@@ -241,7 +210,9 @@ class PciDev : public DmaDevice
* @param size the size of the read
* @param data pointer to the location where the read value should be stored
*/
- virtual void readConfig(int offset, int size, uint8_t *data);
+ virtual void readConfig(int offset, uint8_t *data);
+ virtual void readConfig(int offset, uint16_t *data);
+ virtual void readConfig(int offset, uint32_t *data);
/**
* Serialize this object to the given output stream.
@@ -256,43 +227,4 @@ class PciDev : public DmaDevice
*/
virtual void unserialize(Checkpoint *cp, const std::string &section);
};
-
-inline Fault
-PciDev::readBar(MemReqPtr &req, uint8_t *data)
-{
- using namespace TheISA;
- if (isBAR(req->paddr, 0))
- return readBar0(req, req->paddr - BARAddrs[0], data);
- if (isBAR(req->paddr, 1))
- return readBar1(req, req->paddr - BARAddrs[1], data);
- if (isBAR(req->paddr, 2))
- return readBar2(req, req->paddr - BARAddrs[2], data);
- if (isBAR(req->paddr, 3))
- return readBar3(req, req->paddr - BARAddrs[3], data);
- if (isBAR(req->paddr, 4))
- return readBar4(req, req->paddr - BARAddrs[4], data);
- if (isBAR(req->paddr, 5))
- return readBar5(req, req->paddr - BARAddrs[5], data);
- return genMachineCheckFault();
-}
-
-inline Fault
-PciDev::writeBar(MemReqPtr &req, const uint8_t *data)
-{
- using namespace TheISA;
- if (isBAR(req->paddr, 0))
- return writeBar0(req, req->paddr - BARAddrs[0], data);
- if (isBAR(req->paddr, 1))
- return writeBar1(req, req->paddr - BARAddrs[1], data);
- if (isBAR(req->paddr, 2))
- return writeBar2(req, req->paddr - BARAddrs[2], data);
- if (isBAR(req->paddr, 3))
- return writeBar3(req, req->paddr - BARAddrs[3], data);
- if (isBAR(req->paddr, 4))
- return writeBar4(req, req->paddr - BARAddrs[4], data);
- if (isBAR(req->paddr, 5))
- return writeBar5(req, req->paddr - BARAddrs[5], data);
- return genMachineCheckFault();
-}
-
#endif // __DEV_PCIDEV_HH__
diff --git a/dev/pktfifo.cc b/dev/pktfifo.cc
index 639009be9..922a66912 100644
--- a/dev/pktfifo.cc
+++ b/dev/pktfifo.cc
@@ -38,8 +38,8 @@ PacketFifo::copyout(void *dest, int offset, int len)
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;
@@ -70,8 +70,8 @@ PacketFifo::serialize(const string &base, ostream &os)
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;
@@ -92,7 +92,7 @@ PacketFifo::unserialize(const string &base, Checkpoint *cp,
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);
}
diff --git a/dev/pktfifo.hh b/dev/pktfifo.hh
index e245840a8..336da22d8 100644
--- a/dev/pktfifo.hh
+++ b/dev/pktfifo.hh
@@ -40,11 +40,11 @@ class Checkpoint;
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;
@@ -71,9 +71,9 @@ class PacketFifo
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);
@@ -92,7 +92,7 @@ class PacketFifo
if (empty())
return;
- PacketPtr &packet = fifo.front();
+ EthPacketPtr &packet = fifo.front();
_size -= packet->length;
_size -= packet->slack;
packet->slack = 0;
@@ -111,7 +111,7 @@ class PacketFifo
void remove(iterator i)
{
- PacketPtr &packet = *i;
+ EthPacketPtr &packet = *i;
if (i != fifo.begin()) {
iterator prev = i;
--prev;
diff --git a/dev/sinic.cc b/dev/sinic.cc
index 363994919..b91ef83b0 100644
--- a/dev/sinic.cc
+++ b/dev/sinic.cc
@@ -28,6 +28,7 @@
#include <cstdio>
#include <deque>
+#include <limits>
#include <string>
#include "base/inet.hh"
@@ -36,12 +37,7 @@
#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"
@@ -85,8 +81,7 @@ Base::Base(Params *p)
}
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),
@@ -94,25 +89,6 @@ Device::Device(Params *p)
{
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()
@@ -288,29 +264,6 @@ Device::regStats()
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)
{
@@ -357,73 +310,64 @@ Device::prepareWrite(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 &reg = *(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 &reg = *(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))
@@ -449,72 +393,60 @@ Device::iprRead(Addr daddr, int cpu, uint64_t &result)
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:
@@ -523,7 +455,7 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
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;
@@ -537,7 +469,7 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
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) {
@@ -547,7 +479,7 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
break;
}
- return NoFault;
+ return pioDelay;
}
void
@@ -793,20 +725,13 @@ Device::reset()
}
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)
@@ -892,29 +817,17 @@ Device::rxKick()
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:
@@ -968,20 +881,13 @@ Device::rxKick()
}
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)
@@ -999,7 +905,7 @@ Device::transmit()
}
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());
@@ -1065,7 +971,7 @@ Device::txKick()
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;
}
@@ -1079,28 +985,16 @@ Device::txKick()
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:
@@ -1187,7 +1081,7 @@ Device::transferDone()
}
bool
-Device::rxFilter(const PacketPtr &packet)
+Device::rxFilter(const EthPacketPtr &packet)
{
if (!Regs::get_Config_Filter(regs.Config))
return false;
@@ -1232,7 +1126,7 @@ Device::rxFilter(const PacketPtr &packet)
}
bool
-Device::recvPacket(PacketPtr packet)
+Device::recvPacket(EthPacketPtr packet)
{
rxBytes += packet->length;
rxPackets++;
@@ -1273,7 +1167,7 @@ Device::recvPacket(PacketPtr packet)
//
//
void
-Base::serialize(ostream &os)
+Base::serialize(std::ostream &os)
{
// Serialize the PciDev base class
PciDev::serialize(os);
@@ -1317,7 +1211,7 @@ Base::unserialize(Checkpoint *cp, const std::string &section)
}
void
-Device::serialize(ostream &os)
+Device::serialize(std::ostream &os)
{
// Serialize the PciDev base class
Base::serialize(os);
@@ -1352,7 +1246,7 @@ Device::serialize(ostream &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);
@@ -1481,7 +1375,7 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
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);
@@ -1499,7 +1393,7 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
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);
@@ -1532,30 +1426,11 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
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;
@@ -1588,29 +1463,22 @@ REGISTER_SIM_OBJECT("SinicInt", Interface)
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;
@@ -1623,7 +1491,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
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;
@@ -1632,29 +1500,22 @@ END_DECLARE_SIM_OBJECT_PARAMS(Device)
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"),
@@ -1678,31 +1539,22 @@ END_INIT_SIM_OBJECT_PARAMS(Device)
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;
diff --git a/dev/sinic.hh b/dev/sinic.hh
index 25172fa45..63a8585dc 100644
--- a/dev/sinic.hh
+++ b/dev/sinic.hh
@@ -37,7 +37,6 @@
#include "dev/pcidev.hh"
#include "dev/pktfifo.hh"
#include "dev/sinicreg.hh"
-#include "mem/bus/bus.hh"
#include "sim/eventq.hh"
namespace Sinic {
@@ -91,10 +90,6 @@ class Base : public PciDev
class Device : public Base
{
protected:
- Platform *plat;
- PhysicalMemory *physmem;
-
- protected:
/** Receive State Machine States */
enum RxState {
rxIdle,
@@ -162,10 +157,6 @@ class Device : public Base
uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
- private:
- Addr addr;
- static const Addr size = Regs::Size;
-
protected:
RxState rxState;
PacketFifo rxFifo;
@@ -178,7 +169,7 @@ class Device : public Base
TxState txState;
PacketFifo txFifo;
bool txFull;
- PacketPtr txPacket;
+ EthPacketPtr txPacket;
int txPacketOffset;
int txPacketBytes;
Addr txDmaAddr;
@@ -218,7 +209,7 @@ class Device : public Base
/**
* receive address filter
*/
- bool rxFilter(const PacketPtr &packet);
+ bool rxFilter(const EthPacketPtr &packet);
/**
* device configuration
@@ -230,7 +221,7 @@ class Device : public Base
* device ethernet interface
*/
public:
- bool recvPacket(PacketPtr packet);
+ bool recvPacket(EthPacketPtr packet);
void transferDone();
void setInterface(Interface *i) { assert(!interface); interface = i; }
@@ -238,12 +229,10 @@ class Device : public Base
* 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;
@@ -262,25 +251,16 @@ class Device : public Base
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
@@ -328,17 +308,8 @@ class Device : public Base
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;
@@ -352,7 +323,6 @@ class Device : public Base
Tick dma_read_factor;
Tick dma_write_delay;
Tick dma_write_factor;
- bool dma_no_allocate;
bool rx_thread;
bool tx_thread;
bool rss;
@@ -378,7 +348,7 @@ class Interface : public EtherInt
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(); }
};
diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc
index 81ad9a71d..f35c34138 100644
--- a/dev/tsunami_cchip.cc
+++ b/dev/tsunami_cchip.cc
@@ -80,72 +80,65 @@ TsunamiCChip::read(Packet &pkt)
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");
@@ -163,10 +156,10 @@ TsunamiCChip::read(Packet &pkt)
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");
@@ -180,7 +173,7 @@ TsunamiCChip::read(Packet &pkt)
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;
@@ -197,10 +190,9 @@ TsunamiCChip::write(Packet &pkt)
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;
@@ -215,7 +207,7 @@ TsunamiCChip::write(Packet &pkt)
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++)
{
@@ -252,7 +244,7 @@ TsunamiCChip::write(Packet &pkt)
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);
@@ -261,7 +253,7 @@ TsunamiCChip::write(Packet &pkt)
//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;
@@ -269,14 +261,14 @@ TsunamiCChip::write(Packet &pkt)
//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)
@@ -308,7 +300,7 @@ TsunamiCChip::write(Packet &pkt)
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++)
{
@@ -358,13 +350,13 @@ TsunamiCChip::write(Packet &pkt)
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");
diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc
index ebf3492ac..ed526bdde 100644
--- a/dev/tsunami_io.cc
+++ b/dev/tsunami_io.cc
@@ -447,65 +447,51 @@ TsunamiIO::read(Packet &pkt)
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);
@@ -524,20 +510,15 @@ TsunamiIO::write(Packet &pkt)
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);
@@ -550,38 +531,38 @@ TsunamiIO::write(Packet &pkt)
}
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:
@@ -596,7 +577,7 @@ TsunamiIO::write(Packet &pkt)
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;
diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc
index 66144b816..05b480cb8 100644
--- a/dev/tsunami_pchip.cc
+++ b/dev/tsunami_pchip.cc
@@ -70,75 +70,71 @@ TsunamiPChip::read(Packet &pkt)
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");
@@ -161,50 +157,49 @@ TsunamiPChip::write(Packet &pkt)
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");
diff --git a/dev/uart8250.cc b/dev/uart8250.cc
index 7e2f9d51f..84885456f 100644
--- a/dev/uart8250.cc
+++ b/dev/uart8250.cc
@@ -116,23 +116,17 @@ Uart8250::read(Packet &pkt)
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");
}
@@ -147,7 +141,7 @@ Uart8250::read(Packet &pkt)
break;
case 0x1:
if (!(LCR & 0x80)) { // Intr Enable Register(IER)
- *data = IER;
+ pkt.set(IER);
} else { // DLM divisor latch MSB
;
}
@@ -156,17 +150,17 @@ Uart8250::read(Packet &pkt)
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;
@@ -177,13 +171,13 @@ Uart8250::read(Packet &pkt)
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");
@@ -207,14 +201,12 @@ Uart8250::write(Packet &pkt)
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)
@@ -225,7 +217,7 @@ Uart8250::write(Packet &pkt)
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");
@@ -259,10 +251,10 @@ Uart8250::write(Packet &pkt)
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)
diff --git a/dev/uart8250.hh b/dev/uart8250.hh
index 76b17caf8..19e4438bc 100644
--- a/dev/uart8250.hh
+++ b/dev/uart8250.hh
@@ -44,13 +44,13 @@
* 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;