Significant rework of Packet class interface:
- new constructor guarantees initialization of most fields - flags track status of non-guaranteed fields (addr, size, src) - accessor functions (getAddr() etc.) check status on access - Command & Result classes are nested in Packet class scope - Command now built from vector of behavior bits - string version of Command for tracing - reinitFromRequest() and makeTimingResponse() encapsulate common manipulations of existing packets src/cpu/simple/atomic.cc: src/cpu/simple/base.cc: src/cpu/simple/timing.cc: src/dev/alpha_console.cc: src/dev/ide_ctrl.cc: src/dev/io_device.cc: src/dev/io_device.hh: src/dev/isa_fake.cc: src/dev/ns_gige.cc: src/dev/pciconfigall.cc: src/dev/sinic.cc: src/dev/tsunami_cchip.cc: src/dev/tsunami_io.cc: src/dev/tsunami_pchip.cc: src/dev/uart8250.cc: src/mem/bus.cc: src/mem/bus.hh: src/mem/physical.cc: src/mem/port.cc: src/mem/port.hh: src/mem/request.hh: Update for new Packet interface. --HG-- extra : convert_revision : 9973d09ea4fa61795f23772a7d3995fa4df5c269
This commit is contained in:
parent
da6a7b1263
commit
e533fad711
|
@ -126,31 +126,23 @@ AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
|
|||
// @todo fix me and get the real cpu iD!!!
|
||||
ifetch_req->setCpuNum(0);
|
||||
ifetch_req->setSize(sizeof(MachInst));
|
||||
ifetch_pkt = new Packet;
|
||||
ifetch_pkt->cmd = Read;
|
||||
ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
|
||||
ifetch_pkt->dataStatic(&inst);
|
||||
ifetch_pkt->req = ifetch_req;
|
||||
ifetch_pkt->size = sizeof(MachInst);
|
||||
ifetch_pkt->dest = Packet::Broadcast;
|
||||
|
||||
data_read_req = new Request(true);
|
||||
// @todo fix me and get the real cpu iD!!!
|
||||
data_read_req->setCpuNum(0);
|
||||
data_read_req->setAsid(0);
|
||||
data_read_pkt = new Packet;
|
||||
data_read_pkt->cmd = Read;
|
||||
data_read_pkt = new Packet(data_read_req, Packet::ReadReq,
|
||||
Packet::Broadcast);
|
||||
data_read_pkt->dataStatic(&dataReg);
|
||||
data_read_pkt->req = data_read_req;
|
||||
data_read_pkt->dest = Packet::Broadcast;
|
||||
|
||||
data_write_req = new Request(true);
|
||||
// @todo fix me and get the real cpu iD!!!
|
||||
data_write_req->setCpuNum(0);
|
||||
data_write_req->setAsid(0);
|
||||
data_write_pkt = new Packet;
|
||||
data_write_pkt->cmd = Write;
|
||||
data_write_pkt->req = data_write_req;
|
||||
data_write_pkt->dest = Packet::Broadcast;
|
||||
data_write_pkt = new Packet(data_write_req, Packet::WriteReq,
|
||||
Packet::Broadcast);
|
||||
}
|
||||
|
||||
|
||||
|
@ -260,13 +252,12 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
|
|||
// Now do the access.
|
||||
if (fault == NoFault) {
|
||||
data_read_pkt->reset();
|
||||
data_read_pkt->addr = data_read_req->getPaddr();
|
||||
data_read_pkt->size = sizeof(T);
|
||||
data_read_pkt->reinitFromRequest();
|
||||
|
||||
dcache_complete = dcachePort.sendAtomic(data_read_pkt);
|
||||
dcache_access = true;
|
||||
|
||||
assert(data_read_pkt->result == Success);
|
||||
assert(data_read_pkt->result == Packet::Success);
|
||||
data = data_read_pkt->get<T>();
|
||||
|
||||
}
|
||||
|
@ -342,13 +333,12 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
|
|||
data_write_pkt->reset();
|
||||
data = htog(data);
|
||||
data_write_pkt->dataStatic(&data);
|
||||
data_write_pkt->addr = data_write_req->getPaddr();
|
||||
data_write_pkt->size = sizeof(T);
|
||||
data_write_pkt->reinitFromRequest();
|
||||
|
||||
dcache_complete = dcachePort.sendAtomic(data_write_pkt);
|
||||
dcache_access = true;
|
||||
|
||||
assert(data_write_pkt->result == Success);
|
||||
assert(data_write_pkt->result == Packet::Success);
|
||||
|
||||
if (res && data_write_req->getFlags() & LOCKED) {
|
||||
*res = data_write_req->getScResult();
|
||||
|
|
|
@ -372,7 +372,7 @@ BaseSimpleCPU::setupFetchPacket(Packet *ifetch_pkt)
|
|||
Fault fault = cpuXC->translateInstReq(ifetch_req);
|
||||
|
||||
if (fault == NoFault) {
|
||||
ifetch_pkt->addr = ifetch_req->getPaddr();
|
||||
ifetch_pkt->reinitFromRequest();
|
||||
}
|
||||
|
||||
return fault;
|
||||
|
|
|
@ -187,13 +187,9 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
|
|||
|
||||
// Now do the access.
|
||||
if (fault == NoFault) {
|
||||
Packet *data_read_pkt = new Packet;
|
||||
data_read_pkt->cmd = Read;
|
||||
data_read_pkt->req = data_read_req;
|
||||
Packet *data_read_pkt =
|
||||
new Packet(data_read_req, Packet::ReadReq, Packet::Broadcast);
|
||||
data_read_pkt->dataDynamic<T>(new T);
|
||||
data_read_pkt->addr = data_read_req->getPaddr();
|
||||
data_read_pkt->size = sizeof(T);
|
||||
data_read_pkt->dest = Packet::Broadcast;
|
||||
|
||||
if (!dcachePort.sendTiming(data_read_pkt)) {
|
||||
_status = DcacheRetry;
|
||||
|
@ -268,14 +264,10 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
|
|||
Fault fault = cpuXC->translateDataWriteReq(data_write_req);
|
||||
// Now do the access.
|
||||
if (fault == NoFault) {
|
||||
Packet *data_write_pkt = new Packet;
|
||||
data_write_pkt->cmd = Write;
|
||||
data_write_pkt->req = data_write_req;
|
||||
Packet *data_write_pkt =
|
||||
new Packet(data_write_req, Packet::WriteReq, Packet::Broadcast);
|
||||
data_write_pkt->allocate();
|
||||
data_write_pkt->size = sizeof(T);
|
||||
data_write_pkt->set(data);
|
||||
data_write_pkt->addr = data_write_req->getPaddr();
|
||||
data_write_pkt->dest = Packet::Broadcast;
|
||||
|
||||
if (!dcachePort.sendTiming(data_write_pkt)) {
|
||||
_status = DcacheRetry;
|
||||
|
@ -350,12 +342,8 @@ TimingSimpleCPU::fetch()
|
|||
Request *ifetch_req = new Request(true);
|
||||
ifetch_req->setSize(sizeof(MachInst));
|
||||
|
||||
ifetch_pkt = new Packet;
|
||||
ifetch_pkt->cmd = Read;
|
||||
ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
|
||||
ifetch_pkt->dataStatic(&inst);
|
||||
ifetch_pkt->req = ifetch_req;
|
||||
ifetch_pkt->size = sizeof(MachInst);
|
||||
ifetch_pkt->dest = Packet::Broadcast;
|
||||
|
||||
Fault fault = setupFetchPacket(ifetch_pkt);
|
||||
if (fault == NoFault) {
|
||||
|
@ -441,7 +429,7 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt)
|
|||
{
|
||||
// received a response from the dcache: complete the load or store
|
||||
// instruction
|
||||
assert(pkt->result == Success);
|
||||
assert(pkt->result == Packet::Success);
|
||||
assert(_status == DcacheWaitResponse);
|
||||
_status = Running;
|
||||
|
||||
|
|
|
@ -95,15 +95,15 @@ AlphaConsole::read(Packet *pkt)
|
|||
* machine dependent address swizzle is required?
|
||||
*/
|
||||
|
||||
assert(pkt->result == Unknown);
|
||||
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize);
|
||||
assert(pkt->result == Packet::Unknown);
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
|
||||
pkt->time += pioDelay;
|
||||
Addr daddr = pkt->addr - pioAddr;
|
||||
Addr daddr = pkt->getAddr() - pioAddr;
|
||||
|
||||
pkt->allocate();
|
||||
|
||||
switch (pkt->size)
|
||||
switch (pkt->getSize())
|
||||
{
|
||||
case sizeof(uint32_t):
|
||||
switch (daddr)
|
||||
|
@ -124,7 +124,7 @@ AlphaConsole::read(Packet *pkt)
|
|||
/* Old console code read in everyting as a 32bit int
|
||||
* we now break that for better error checking.
|
||||
*/
|
||||
pkt->result = BadAddress;
|
||||
pkt->result = Packet::BadAddress;
|
||||
}
|
||||
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr,
|
||||
pkt->get<uint32_t>());
|
||||
|
@ -181,9 +181,10 @@ AlphaConsole::read(Packet *pkt)
|
|||
pkt->get<uint64_t>());
|
||||
break;
|
||||
default:
|
||||
pkt->result = BadAddress;
|
||||
pkt->result = Packet::BadAddress;
|
||||
}
|
||||
if (pkt->result == Unknown) pkt->result = Success;
|
||||
if (pkt->result == Packet::Unknown)
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
@ -192,12 +193,12 @@ AlphaConsole::write(Packet *pkt)
|
|||
{
|
||||
pkt->time += pioDelay;
|
||||
|
||||
assert(pkt->result == Unknown);
|
||||
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize);
|
||||
Addr daddr = pkt->addr - pioAddr;
|
||||
assert(pkt->result == Packet::Unknown);
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
Addr daddr = pkt->getAddr() - pioAddr;
|
||||
|
||||
uint64_t val = pkt->get<uint64_t>();
|
||||
assert(pkt->size == sizeof(uint64_t));
|
||||
assert(pkt->getSize() == sizeof(uint64_t));
|
||||
|
||||
switch (daddr) {
|
||||
case offsetof(AlphaAccess, diskUnit):
|
||||
|
@ -240,7 +241,7 @@ AlphaConsole::write(Packet *pkt)
|
|||
panic("Unknown 64bit access, %#x\n", daddr);
|
||||
}
|
||||
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
|
||||
return pioDelay;
|
||||
}
|
||||
|
|
|
@ -432,19 +432,19 @@ IdeController::read(Packet *pkt)
|
|||
|
||||
pkt->time += pioDelay;
|
||||
pkt->allocate();
|
||||
if (pkt->size != 1 && pkt->size != 2 && pkt->size !=4)
|
||||
panic("Bad IDE read size: %d\n", pkt->size);
|
||||
if (pkt->getSize() != 1 && pkt->getSize() != 2 && pkt->getSize() !=4)
|
||||
panic("Bad IDE read size: %d\n", pkt->getSize());
|
||||
|
||||
parseAddr(pkt->addr, offset, channel, reg_type);
|
||||
parseAddr(pkt->getAddr(), offset, channel, reg_type);
|
||||
|
||||
if (!io_enabled) {
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
switch (reg_type) {
|
||||
case BMI_BLOCK:
|
||||
switch (pkt->size) {
|
||||
switch (pkt->getSize()) {
|
||||
case sizeof(uint8_t):
|
||||
pkt->set(bmi_regs.data[offset]);
|
||||
break;
|
||||
|
@ -455,7 +455,7 @@ IdeController::read(Packet *pkt)
|
|||
pkt->set(*(uint32_t*)&bmi_regs.data[offset]);
|
||||
break;
|
||||
default:
|
||||
panic("IDE read of BMI reg invalid size: %#x\n", pkt->size);
|
||||
panic("IDE read of BMI reg invalid size: %#x\n", pkt->getSize());
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -470,7 +470,7 @@ IdeController::read(Packet *pkt)
|
|||
|
||||
switch (offset) {
|
||||
case DATA_OFFSET:
|
||||
switch (pkt->size) {
|
||||
switch (pkt->getSize()) {
|
||||
case sizeof(uint16_t):
|
||||
disks[disk]->read(offset, reg_type, pkt->getPtr<uint8_t>());
|
||||
break;
|
||||
|
@ -482,30 +482,30 @@ IdeController::read(Packet *pkt)
|
|||
break;
|
||||
|
||||
default:
|
||||
panic("IDE read of data reg invalid size: %#x\n", pkt->size);
|
||||
panic("IDE read of data reg invalid size: %#x\n", pkt->getSize());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (pkt->size == sizeof(uint8_t)) {
|
||||
if (pkt->getSize() == 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", pkt->size);
|
||||
panic("IDE read of command reg of invalid size: %#x\n", pkt->getSize());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
panic("IDE controller read of unknown register block type!\n");
|
||||
}
|
||||
if (pkt->size == 1)
|
||||
if (pkt->getSize() == 1)
|
||||
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
|
||||
offset, pkt->size, (uint32_t)pkt->get<uint8_t>());
|
||||
else if (pkt->size == 2)
|
||||
offset, pkt->getSize(), (uint32_t)pkt->get<uint8_t>());
|
||||
else if (pkt->getSize() == 2)
|
||||
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
|
||||
offset, pkt->size, pkt->get<uint16_t>());
|
||||
offset, pkt->getSize(), pkt->get<uint16_t>());
|
||||
else
|
||||
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
|
||||
offset, pkt->size, pkt->get<uint32_t>());
|
||||
offset, pkt->getSize(), pkt->get<uint32_t>());
|
||||
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
@ -520,10 +520,10 @@ IdeController::write(Packet *pkt)
|
|||
|
||||
pkt->time += pioDelay;
|
||||
|
||||
parseAddr(pkt->addr, offset, channel, reg_type);
|
||||
parseAddr(pkt->getAddr(), offset, channel, reg_type);
|
||||
|
||||
if (!io_enabled) {
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
DPRINTF(IdeCtrl, "io not enabled\n");
|
||||
return pioDelay;
|
||||
}
|
||||
|
@ -531,7 +531,7 @@ IdeController::write(Packet *pkt)
|
|||
switch (reg_type) {
|
||||
case BMI_BLOCK:
|
||||
if (!bm_enabled) {
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
@ -539,8 +539,8 @@ IdeController::write(Packet *pkt)
|
|||
// Bus master IDE command register
|
||||
case BMIC1:
|
||||
case BMIC0:
|
||||
if (pkt->size != sizeof(uint8_t))
|
||||
panic("Invalid BMIC write size: %x\n", pkt->size);
|
||||
if (pkt->getSize() != sizeof(uint8_t))
|
||||
panic("Invalid BMIC write size: %x\n", pkt->getSize());
|
||||
|
||||
// select the current disk based on DEV bit
|
||||
disk = getDisk(channel);
|
||||
|
@ -595,8 +595,8 @@ IdeController::write(Packet *pkt)
|
|||
// Bus master IDE status register
|
||||
case BMIS0:
|
||||
case BMIS1:
|
||||
if (pkt->size != sizeof(uint8_t))
|
||||
panic("Invalid BMIS write size: %x\n", pkt->size);
|
||||
if (pkt->getSize() != sizeof(uint8_t))
|
||||
panic("Invalid BMIS write size: %x\n", pkt->getSize());
|
||||
|
||||
oldVal = bmi_regs.chan[channel].bmis;
|
||||
newVal = pkt->get<uint8_t>();
|
||||
|
@ -622,22 +622,22 @@ IdeController::write(Packet *pkt)
|
|||
case BMIDTP0:
|
||||
case BMIDTP1:
|
||||
{
|
||||
if (pkt->size != sizeof(uint32_t))
|
||||
panic("Invalid BMIDTP write size: %x\n", pkt->size);
|
||||
if (pkt->getSize() != sizeof(uint32_t))
|
||||
panic("Invalid BMIDTP write size: %x\n", pkt->getSize());
|
||||
|
||||
bmi_regs.chan[channel].bmidtp = htole(pkt->get<uint32_t>() & ~0x3);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (pkt->size != sizeof(uint8_t) &&
|
||||
pkt->size != sizeof(uint16_t) &&
|
||||
pkt->size != sizeof(uint32_t))
|
||||
if (pkt->getSize() != sizeof(uint8_t) &&
|
||||
pkt->getSize() != sizeof(uint16_t) &&
|
||||
pkt->getSize() != sizeof(uint32_t))
|
||||
panic("IDE controller write of invalid write size: %x\n",
|
||||
pkt->size);
|
||||
pkt->getSize());
|
||||
|
||||
// do a default copy of data into the registers
|
||||
memcpy(&bmi_regs.data[offset], pkt->getPtr<uint8_t>(), pkt->size);
|
||||
memcpy(&bmi_regs.data[offset], pkt->getPtr<uint8_t>(), pkt->getSize());
|
||||
}
|
||||
break;
|
||||
case COMMAND_BLOCK:
|
||||
|
@ -654,7 +654,7 @@ IdeController::write(Packet *pkt)
|
|||
|
||||
switch (offset) {
|
||||
case DATA_OFFSET:
|
||||
switch (pkt->size) {
|
||||
switch (pkt->getSize()) {
|
||||
case sizeof(uint16_t):
|
||||
disks[disk]->write(offset, reg_type, pkt->getPtr<uint8_t>());
|
||||
break;
|
||||
|
@ -665,32 +665,32 @@ IdeController::write(Packet *pkt)
|
|||
sizeof(uint16_t));
|
||||
break;
|
||||
default:
|
||||
panic("IDE write of data reg invalid size: %#x\n", pkt->size);
|
||||
panic("IDE write of data reg invalid size: %#x\n", pkt->getSize());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (pkt->size == sizeof(uint8_t)) {
|
||||
if (pkt->getSize() == 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", pkt->size);
|
||||
panic("IDE write of command reg of invalid size: %#x\n", pkt->getSize());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
panic("IDE controller write of unknown register block type!\n");
|
||||
}
|
||||
|
||||
if (pkt->size == 1)
|
||||
if (pkt->getSize() == 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)
|
||||
offset, pkt->getSize(), (uint32_t)pkt->get<uint8_t>());
|
||||
else if (pkt->getSize() == 2)
|
||||
DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
|
||||
offset, pkt->size, pkt->get<uint16_t>());
|
||||
offset, pkt->getSize(), pkt->get<uint16_t>());
|
||||
else
|
||||
DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
|
||||
offset, pkt->size, pkt->get<uint32_t>());
|
||||
offset, pkt->getSize(), pkt->get<uint32_t>());
|
||||
|
||||
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ PioPort::recvRetry()
|
|||
void
|
||||
PioPort::SendEvent::process()
|
||||
{
|
||||
if (port->Port::sendTiming(packet) == Success)
|
||||
if (port->Port::sendTiming(packet))
|
||||
return;
|
||||
|
||||
port->transmitList.push_back(packet);
|
||||
|
@ -79,9 +79,9 @@ PioPort::recvTiming(Packet *pkt)
|
|||
{
|
||||
device->recvAtomic(pkt);
|
||||
// turn packet around to go back to requester
|
||||
pkt->dest = pkt->src;
|
||||
pkt->makeTimingResponse();
|
||||
sendTiming(pkt, pkt->time - pkt->req->getTime());
|
||||
return Success;
|
||||
return true;
|
||||
}
|
||||
|
||||
PioDevice::~PioDevice()
|
||||
|
@ -116,7 +116,7 @@ DmaPort::recvTiming(Packet *pkt)
|
|||
{
|
||||
if (pkt->senderState) {
|
||||
DmaReqState *state;
|
||||
state = (DmaReqState*)pkt->senderState;
|
||||
state = dynamic_cast<DmaReqState*>(pkt->senderState);
|
||||
state->completionEvent->schedule(pkt->time - pkt->req->getTime());
|
||||
delete pkt->req;
|
||||
delete pkt;
|
||||
|
@ -125,7 +125,7 @@ DmaPort::recvTiming(Packet *pkt)
|
|||
delete pkt;
|
||||
}
|
||||
|
||||
return Success;
|
||||
return Packet::Success;
|
||||
}
|
||||
|
||||
DmaDevice::DmaDevice(Params *p)
|
||||
|
@ -135,7 +135,7 @@ DmaDevice::DmaDevice(Params *p)
|
|||
void
|
||||
DmaPort::SendEvent::process()
|
||||
{
|
||||
if (port->Port::sendTiming(packet) == Success)
|
||||
if (port->Port::sendTiming(packet))
|
||||
return;
|
||||
|
||||
port->transmitList.push_back(packet);
|
||||
|
@ -148,54 +148,39 @@ DmaPort::recvRetry()
|
|||
transmitList.pop_front();
|
||||
return pkt;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DmaPort::dmaAction(Command cmd, Addr addr, int size, Event *event,
|
||||
DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
|
||||
uint8_t *data)
|
||||
{
|
||||
|
||||
assert(event);
|
||||
|
||||
int prevSize = 0;
|
||||
Packet basePkt;
|
||||
Request baseReq(false);
|
||||
|
||||
basePkt.flags = 0;
|
||||
basePkt.coherence = NULL;
|
||||
basePkt.senderState = NULL;
|
||||
basePkt.dest = Packet::Broadcast;
|
||||
basePkt.cmd = cmd;
|
||||
basePkt.result = Unknown;
|
||||
basePkt.req = NULL;
|
||||
// baseReq.nicReq = true;
|
||||
baseReq.setTime(curTick);
|
||||
|
||||
for (ChunkGenerator gen(addr, size, peerBlockSize());
|
||||
!gen.done(); gen.next()) {
|
||||
Packet *pkt = new Packet(basePkt);
|
||||
Request *req = new Request(baseReq);
|
||||
pkt->addr = gen.addr();
|
||||
pkt->size = gen.size();
|
||||
pkt->req = req;
|
||||
pkt->req->setPaddr(pkt->addr);
|
||||
pkt->req->setSize(pkt->size);
|
||||
Request *req = new Request(false);
|
||||
req->setPaddr(gen.addr());
|
||||
req->setSize(gen.size());
|
||||
req->setTime(curTick);
|
||||
Packet *pkt = new Packet(req, cmd, Packet::Broadcast);
|
||||
|
||||
// Increment the data pointer on a write
|
||||
if (data)
|
||||
pkt->dataStatic(data + prevSize) ;
|
||||
prevSize += pkt->size;
|
||||
|
||||
prevSize += gen.size();
|
||||
|
||||
// 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;
|
||||
pkt->senderState = new DmaReqState(event, true);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -208,12 +193,12 @@ DmaPort::sendDma(Packet *pkt)
|
|||
/* MemState state = device->platform->system->memState;
|
||||
|
||||
if (state == Timing) {
|
||||
if (sendTiming(pkt) == Failure)
|
||||
if (!sendTiming(pkt))
|
||||
transmitList.push_back(&packet);
|
||||
} else if (state == Atomic) {*/
|
||||
sendAtomic(pkt);
|
||||
if (pkt->senderState) {
|
||||
DmaReqState *state = (DmaReqState*)pkt->senderState;
|
||||
DmaReqState *state = dynamic_cast<DmaReqState*>(pkt->senderState);
|
||||
state->completionEvent->schedule(curTick + (pkt->time - pkt->req->getTime()) +1);
|
||||
}
|
||||
pendingCount--;
|
||||
|
|
|
@ -115,7 +115,7 @@ class PioPort : public Port
|
|||
};
|
||||
|
||||
|
||||
struct DmaReqState
|
||||
struct DmaReqState : public Packet::SenderState
|
||||
{
|
||||
Event *completionEvent;
|
||||
bool final;
|
||||
|
@ -173,7 +173,7 @@ class DmaPort : public Port
|
|||
public:
|
||||
DmaPort(DmaDevice *dev, Platform *p);
|
||||
|
||||
void dmaAction(Command cmd, Addr addr, int size, Event *event,
|
||||
void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
|
||||
uint8_t *data = NULL);
|
||||
|
||||
bool dmaPending() { return pendingCount > 0; }
|
||||
|
@ -207,7 +207,7 @@ class PioDevice : public MemObject
|
|||
/** As far as the devices are concerned they only accept atomic transactions
|
||||
* which are converted to either a write or a read. */
|
||||
Tick recvAtomic(Packet *pkt)
|
||||
{ return pkt->cmd == Read ? this->read(pkt) : this->write(pkt); }
|
||||
{ return pkt->isRead() ? this->read(pkt) : this->write(pkt); }
|
||||
|
||||
/** Pure virtual function that the device must implement. Called when a read
|
||||
* command is recieved by the port.
|
||||
|
@ -305,10 +305,10 @@ class DmaDevice : public PioDevice
|
|||
virtual ~DmaDevice();
|
||||
|
||||
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data)
|
||||
{ dmaPort->dmaAction(Write, addr, size, event, data) ; }
|
||||
{ dmaPort->dmaAction(Packet::WriteReq, addr, size, event, data) ; }
|
||||
|
||||
void dmaRead(Addr addr, int size, Event *event, uint8_t *data = NULL)
|
||||
{ dmaPort->dmaAction(Read, addr, size, event, data); }
|
||||
{ dmaPort->dmaAction(Packet::ReadReq, addr, size, event, data); }
|
||||
|
||||
bool dmaPending() { return dmaPort->dmaPending(); }
|
||||
|
||||
|
|
|
@ -51,14 +51,14 @@ IsaFake::IsaFake(Params *p)
|
|||
Tick
|
||||
IsaFake::read(Packet *pkt)
|
||||
{
|
||||
assert(pkt->result == Unknown);
|
||||
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize);
|
||||
assert(pkt->result == Packet::Unknown);
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
|
||||
pkt->time += pioDelay;
|
||||
|
||||
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->addr, pkt->size);
|
||||
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());
|
||||
|
||||
switch (pkt->size) {
|
||||
switch (pkt->getSize()) {
|
||||
pkt->set(0xFFFFFFFFFFFFFFFFULL);
|
||||
break;
|
||||
case sizeof(uint32_t):
|
||||
|
@ -73,7 +73,7 @@ IsaFake::read(Packet *pkt)
|
|||
default:
|
||||
panic("invalid access size(?) for PCI configspace!\n");
|
||||
}
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
@ -81,8 +81,8 @@ Tick
|
|||
IsaFake::write(Packet *pkt)
|
||||
{
|
||||
pkt->time += pioDelay;
|
||||
DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->addr, pkt->size);
|
||||
pkt->result = Success;
|
||||
DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize());
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
|
|
@ -496,9 +496,9 @@ NSGigE::read(Packet *pkt)
|
|||
pkt->allocate();
|
||||
|
||||
//The mask is to give you only the offset into the device register file
|
||||
Addr daddr = pkt->addr & 0xfff;
|
||||
Addr daddr = pkt->getAddr() & 0xfff;
|
||||
DPRINTF(EthernetPIO, "read da=%#x pa=%#x size=%d\n",
|
||||
daddr, pkt->addr, pkt->size);
|
||||
daddr, pkt->getAddr(), pkt->getSize());
|
||||
|
||||
|
||||
// there are some reserved registers, you can see ns_gige_reg.h and
|
||||
|
@ -506,25 +506,25 @@ NSGigE::read(Packet *pkt)
|
|||
if (daddr > LAST && daddr <= RESERVED) {
|
||||
panic("Accessing reserved register");
|
||||
} else if (daddr > RESERVED && daddr <= 0x3FC) {
|
||||
if (pkt->size == sizeof(uint8_t))
|
||||
if (pkt->getSize() == sizeof(uint8_t))
|
||||
readConfig(daddr & 0xff, pkt->getPtr<uint8_t>());
|
||||
if (pkt->size == sizeof(uint16_t))
|
||||
if (pkt->getSize() == sizeof(uint16_t))
|
||||
readConfig(daddr & 0xff, pkt->getPtr<uint16_t>());
|
||||
if (pkt->size == sizeof(uint32_t))
|
||||
if (pkt->getSize() == sizeof(uint32_t))
|
||||
readConfig(daddr & 0xff, pkt->getPtr<uint32_t>());
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::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
|
||||
pkt->set<uint32_t>(0);
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
} else if (daddr > 0x3FC)
|
||||
panic("Something is messed up!\n");
|
||||
|
||||
assert(pkt->size == sizeof(uint32_t));
|
||||
assert(pkt->getSize() == sizeof(uint32_t));
|
||||
uint32_t ® = *pkt->getPtr<uint32_t>();
|
||||
uint16_t rfaddr;
|
||||
|
||||
|
@ -715,7 +715,7 @@ NSGigE::read(Packet *pkt)
|
|||
DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n",
|
||||
daddr, reg, reg);
|
||||
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
@ -724,27 +724,27 @@ NSGigE::write(Packet *pkt)
|
|||
{
|
||||
assert(ioEnable);
|
||||
|
||||
Addr daddr = pkt->addr & 0xfff;
|
||||
Addr daddr = pkt->getAddr() & 0xfff;
|
||||
DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n",
|
||||
daddr, pkt->addr, pkt->size);
|
||||
daddr, pkt->getAddr(), pkt->getSize());
|
||||
|
||||
pkt->time += pioDelay;
|
||||
|
||||
if (daddr > LAST && daddr <= RESERVED) {
|
||||
panic("Accessing reserved register");
|
||||
} else if (daddr > RESERVED && daddr <= 0x3FC) {
|
||||
if (pkt->size == sizeof(uint8_t))
|
||||
if (pkt->getSize() == sizeof(uint8_t))
|
||||
writeConfig(daddr & 0xff, pkt->get<uint8_t>());
|
||||
if (pkt->size == sizeof(uint16_t))
|
||||
if (pkt->getSize() == sizeof(uint16_t))
|
||||
writeConfig(daddr & 0xff, pkt->get<uint16_t>());
|
||||
if (pkt->size == sizeof(uint32_t))
|
||||
if (pkt->getSize() == sizeof(uint32_t))
|
||||
writeConfig(daddr & 0xff, pkt->get<uint32_t>());
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
} else if (daddr > 0x3FC)
|
||||
panic("Something is messed up!\n");
|
||||
|
||||
if (pkt->size == sizeof(uint32_t)) {
|
||||
if (pkt->getSize() == sizeof(uint32_t)) {
|
||||
uint32_t reg = pkt->get<uint32_t>();
|
||||
uint16_t rfaddr;
|
||||
|
||||
|
@ -1131,7 +1131,7 @@ NSGigE::write(Packet *pkt)
|
|||
} else {
|
||||
panic("Invalid Request Size");
|
||||
}
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,10 +91,10 @@ PciConfigAll::startup()
|
|||
Tick
|
||||
PciConfigAll::read(Packet *pkt)
|
||||
{
|
||||
assert(pkt->result == Unknown);
|
||||
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize);
|
||||
assert(pkt->result == Packet::Unknown);
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
|
||||
Addr daddr = pkt->addr - pioAddr;
|
||||
Addr daddr = pkt->getAddr() - pioAddr;
|
||||
int device = (daddr >> 11) & 0x1F;
|
||||
int func = (daddr >> 8) & 0x7;
|
||||
int reg = daddr & 0xFF;
|
||||
|
@ -102,10 +102,10 @@ PciConfigAll::read(Packet *pkt)
|
|||
pkt->time += pioDelay;
|
||||
pkt->allocate();
|
||||
|
||||
DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt->addr, daddr,
|
||||
pkt->size);
|
||||
DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt->getAddr(), daddr,
|
||||
pkt->getSize());
|
||||
|
||||
switch (pkt->size) {
|
||||
switch (pkt->getSize()) {
|
||||
case sizeof(uint32_t):
|
||||
if (devices[device][func] == NULL)
|
||||
pkt->set<uint32_t>(0xFFFFFFFF);
|
||||
|
@ -127,7 +127,7 @@ PciConfigAll::read(Packet *pkt)
|
|||
default:
|
||||
panic("invalid access size(?) for PCI configspace!\n");
|
||||
}
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
@ -136,11 +136,11 @@ PciConfigAll::write(Packet *pkt)
|
|||
{
|
||||
pkt->time += pioDelay;
|
||||
|
||||
assert(pkt->result == Unknown);
|
||||
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize);
|
||||
assert(pkt->size == sizeof(uint8_t) || pkt->size == sizeof(uint16_t) ||
|
||||
pkt->size == sizeof(uint32_t));
|
||||
Addr daddr = pkt->addr - pioAddr;
|
||||
assert(pkt->result == Packet::Unknown);
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
assert(pkt->getSize() == sizeof(uint8_t) || pkt->getSize() == sizeof(uint16_t) ||
|
||||
pkt->getSize() == sizeof(uint32_t));
|
||||
Addr daddr = pkt->getAddr() - pioAddr;
|
||||
|
||||
int device = (daddr >> 11) & 0x1F;
|
||||
int func = (daddr >> 8) & 0x7;
|
||||
|
@ -150,9 +150,9 @@ PciConfigAll::write(Packet *pkt)
|
|||
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, pkt->get<uint32_t>());
|
||||
pkt->getAddr(), pkt->getSize(), pkt->get<uint32_t>());
|
||||
|
||||
switch (pkt->size) {
|
||||
switch (pkt->getSize()) {
|
||||
case sizeof(uint8_t):
|
||||
devices[device][func]->writeConfig(reg, pkt->get<uint8_t>());
|
||||
break;
|
||||
|
@ -165,7 +165,7 @@ PciConfigAll::write(Packet *pkt)
|
|||
default:
|
||||
panic("invalid pci config write size\n");
|
||||
}
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
|
|
@ -315,10 +315,10 @@ Tick
|
|||
Device::read(Packet *pkt)
|
||||
{
|
||||
assert(config.command & PCI_CMD_MSE);
|
||||
assert(pkt->addr >= BARAddrs[0] && pkt->size < BARSize[0]);
|
||||
assert(pkt->getAddr() >= BARAddrs[0] && pkt->getSize() < BARSize[0]);
|
||||
|
||||
int cpu = pkt->req->getCpuNum();
|
||||
Addr daddr = pkt->addr - BARAddrs[0];
|
||||
Addr daddr = pkt->getAddr() - BARAddrs[0];
|
||||
Addr index = daddr >> Regs::VirtualShift;
|
||||
Addr raddr = daddr & Regs::VirtualMask;
|
||||
|
||||
|
@ -327,28 +327,28 @@ Device::read(Packet *pkt)
|
|||
|
||||
if (!regValid(raddr))
|
||||
panic("invalid register: cpu=%d vnic=%d da=%#x pa=%#x size=%d",
|
||||
cpu, index, daddr, pkt->addr, pkt->size);
|
||||
cpu, index, daddr, pkt->getAddr(), pkt->getSize());
|
||||
|
||||
const Regs::Info &info = regInfo(raddr);
|
||||
if (!info.read)
|
||||
panic("read %s (write only): "
|
||||
"cpu=%d vnic=%d da=%#x pa=%#x size=%d",
|
||||
info.name, cpu, index, daddr, pkt->addr, pkt->size);
|
||||
info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize());
|
||||
|
||||
panic("read %s (invalid size): "
|
||||
"cpu=%d vnic=%d da=%#x pa=%#x size=%d",
|
||||
info.name, cpu, index, daddr, pkt->addr, pkt->size);
|
||||
info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize());
|
||||
|
||||
prepareRead(cpu, index);
|
||||
|
||||
uint64_t value = 0;
|
||||
if (pkt->size == 4) {
|
||||
if (pkt->getSize() == 4) {
|
||||
uint32_t reg = regData32(raddr);
|
||||
pkt->set(reg);
|
||||
value = reg;
|
||||
}
|
||||
|
||||
if (pkt->size == 8) {
|
||||
if (pkt->getSize() == 8) {
|
||||
uint64_t reg = regData64(raddr);
|
||||
pkt->set(reg);
|
||||
value = reg;
|
||||
|
@ -356,7 +356,7 @@ Device::read(Packet *pkt)
|
|||
|
||||
DPRINTF(EthernetPIO,
|
||||
"read %s: cpu=%d vnic=%d da=%#x pa=%#x size=%d val=%#x\n",
|
||||
info.name, cpu, index, daddr, pkt->addr, pkt->size, value);
|
||||
info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize(), value);
|
||||
|
||||
// reading the interrupt status register has the side effect of
|
||||
// clearing it
|
||||
|
@ -403,10 +403,10 @@ Tick
|
|||
Device::write(Packet *pkt)
|
||||
{
|
||||
assert(config.command & PCI_CMD_MSE);
|
||||
assert(pkt->addr >= BARAddrs[0] && pkt->size < BARSize[0]);
|
||||
assert(pkt->getAddr() >= BARAddrs[0] && pkt->getSize() < BARSize[0]);
|
||||
|
||||
int cpu = pkt->req->getCpuNum();
|
||||
Addr daddr = pkt->addr - BARAddrs[0];
|
||||
Addr daddr = pkt->getAddr() - BARAddrs[0];
|
||||
Addr index = daddr >> Regs::VirtualShift;
|
||||
Addr raddr = daddr & Regs::VirtualMask;
|
||||
|
||||
|
@ -414,25 +414,25 @@ Device::write(Packet *pkt)
|
|||
|
||||
if (!regValid(raddr))
|
||||
panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d",
|
||||
cpu, daddr, pkt->addr, pkt->size);
|
||||
cpu, daddr, pkt->getAddr(), pkt->getSize());
|
||||
|
||||
const Regs::Info &info = regInfo(raddr);
|
||||
if (!info.write)
|
||||
panic("write %s (read only): "
|
||||
"cpu=%d vnic=%d da=%#x pa=%#x size=%d",
|
||||
info.name, cpu, index, daddr, pkt->addr, pkt->size);
|
||||
info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize());
|
||||
|
||||
if (pkt->size != info.size)
|
||||
if (pkt->getSize() != info.size)
|
||||
panic("write %s (invalid size): "
|
||||
"cpu=%d vnic=%d da=%#x pa=%#x size=%d",
|
||||
info.name, cpu, index, daddr, pkt->addr, pkt->size);
|
||||
info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize());
|
||||
|
||||
VirtualReg &vnic = virtualRegs[index];
|
||||
|
||||
DPRINTF(EthernetPIO,
|
||||
"write %s vnic %d: cpu=%d val=%#x da=%#x pa=%#x size=%d\n",
|
||||
info.name, index, cpu, info.size == 4 ? pkt->get<uint32_t>() :
|
||||
pkt->get<uint64_t>(), daddr, pkt->addr, pkt->size);
|
||||
pkt->get<uint64_t>(), daddr, pkt->getAddr(), pkt->getSize());
|
||||
|
||||
prepareWrite(cpu, index);
|
||||
|
||||
|
|
|
@ -71,17 +71,17 @@ TsunamiCChip::TsunamiCChip(Params *p)
|
|||
Tick
|
||||
TsunamiCChip::read(Packet *pkt)
|
||||
{
|
||||
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->addr, pkt->size);
|
||||
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());
|
||||
|
||||
assert(pkt->result == Unknown);
|
||||
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize);
|
||||
assert(pkt->result == Packet::Unknown);
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
|
||||
pkt->time += pioDelay;
|
||||
Addr regnum = (pkt->addr - pioAddr) >> 6;
|
||||
Addr daddr = (pkt->addr - pioAddr);
|
||||
Addr regnum = (pkt->getAddr() - pioAddr) >> 6;
|
||||
Addr daddr = (pkt->getAddr() - pioAddr);
|
||||
|
||||
pkt->allocate();
|
||||
switch (pkt->size) {
|
||||
switch (pkt->getSize()) {
|
||||
|
||||
case sizeof(uint64_t):
|
||||
if (daddr & TSDEV_CC_BDIMS)
|
||||
|
@ -173,9 +173,9 @@ 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, pkt->get<uint64_t>());
|
||||
regnum, pkt->getSize(), pkt->get<uint64_t>());
|
||||
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
@ -185,14 +185,14 @@ TsunamiCChip::write(Packet *pkt)
|
|||
pkt->time += pioDelay;
|
||||
|
||||
|
||||
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize);
|
||||
Addr daddr = pkt->addr - pioAddr;
|
||||
Addr regnum = (pkt->addr - pioAddr) >> 6 ;
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
Addr daddr = pkt->getAddr() - pioAddr;
|
||||
Addr regnum = (pkt->getAddr() - pioAddr) >> 6 ;
|
||||
|
||||
|
||||
assert(pkt->size == sizeof(uint64_t));
|
||||
assert(pkt->getSize() == sizeof(uint64_t));
|
||||
|
||||
DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt->addr, pkt->get<uint64_t>());
|
||||
DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt->getAddr(), pkt->get<uint64_t>());
|
||||
|
||||
bool supportedWrite = false;
|
||||
|
||||
|
@ -362,7 +362,7 @@ TsunamiCChip::write(Packet *pkt)
|
|||
panic("default in cchip read reached, accessing 0x%x\n");
|
||||
} // swtich(regnum)
|
||||
} // not BIG_TSUNAMI write
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
|
|
@ -438,18 +438,18 @@ TsunamiIO::frequency() const
|
|||
Tick
|
||||
TsunamiIO::read(Packet *pkt)
|
||||
{
|
||||
assert(pkt->result == Unknown);
|
||||
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize);
|
||||
assert(pkt->result == Packet::Unknown);
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
|
||||
pkt->time += pioDelay;
|
||||
Addr daddr = pkt->addr - pioAddr;
|
||||
Addr daddr = pkt->getAddr() - pioAddr;
|
||||
|
||||
DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt->addr,
|
||||
pkt->size, daddr);
|
||||
DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt->getAddr(),
|
||||
pkt->getSize(), daddr);
|
||||
|
||||
pkt->allocate();
|
||||
|
||||
if (pkt->size == sizeof(uint8_t)) {
|
||||
if (pkt->getSize() == sizeof(uint8_t)) {
|
||||
switch(daddr) {
|
||||
// PIC1 mask read
|
||||
case TSDEV_PIC1_MASK:
|
||||
|
@ -487,18 +487,18 @@ TsunamiIO::read(Packet *pkt)
|
|||
pkt->set(0x00);
|
||||
break;
|
||||
default:
|
||||
panic("I/O Read - va%#x size %d\n", pkt->addr, pkt->size);
|
||||
panic("I/O Read - va%#x size %d\n", pkt->getAddr(), pkt->getSize());
|
||||
}
|
||||
} else if (pkt->size == sizeof(uint64_t)) {
|
||||
} else if (pkt->getSize() == sizeof(uint64_t)) {
|
||||
if (daddr == TSDEV_PIC1_ISR)
|
||||
pkt->set<uint64_t>(picr);
|
||||
else
|
||||
panic("I/O Read - invalid addr - va %#x size %d\n",
|
||||
pkt->addr, pkt->size);
|
||||
pkt->getAddr(), pkt->getSize());
|
||||
} else {
|
||||
panic("I/O Read - invalid size - va %#x size %d\n", pkt->addr, pkt->size);
|
||||
panic("I/O Read - invalid size - va %#x size %d\n", pkt->getAddr(), pkt->getSize());
|
||||
}
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
@ -507,14 +507,14 @@ TsunamiIO::write(Packet *pkt)
|
|||
{
|
||||
pkt->time += pioDelay;
|
||||
|
||||
assert(pkt->result == Unknown);
|
||||
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize);
|
||||
Addr daddr = pkt->addr - pioAddr;
|
||||
assert(pkt->result == Packet::Unknown);
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
Addr daddr = pkt->getAddr() - pioAddr;
|
||||
|
||||
DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n",
|
||||
pkt->addr, pkt->size, pkt->addr & 0xfff, (uint32_t)pkt->get<uint8_t>());
|
||||
pkt->getAddr(), pkt->getSize(), pkt->getAddr() & 0xfff, (uint32_t)pkt->get<uint8_t>());
|
||||
|
||||
assert(pkt->size == sizeof(uint8_t));
|
||||
assert(pkt->getSize() == sizeof(uint8_t));
|
||||
|
||||
switch(daddr) {
|
||||
case TSDEV_PIC1_MASK:
|
||||
|
@ -577,10 +577,10 @@ 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, pkt->get<uint8_t>());
|
||||
panic("I/O Write - va%#x size %d data %#x\n", pkt->getAddr(), pkt->getSize(), pkt->get<uint8_t>());
|
||||
}
|
||||
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,17 +67,17 @@ TsunamiPChip::TsunamiPChip(Params *p)
|
|||
Tick
|
||||
TsunamiPChip::read(Packet *pkt)
|
||||
{
|
||||
assert(pkt->result == Unknown);
|
||||
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize);
|
||||
assert(pkt->result == Packet::Unknown);
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
|
||||
|
||||
pkt->time += pioDelay;
|
||||
pkt->allocate();
|
||||
Addr daddr = (pkt->addr - pioAddr) >> 6;;
|
||||
assert(pkt->size == sizeof(uint64_t));
|
||||
Addr daddr = (pkt->getAddr() - pioAddr) >> 6;;
|
||||
assert(pkt->getSize() == sizeof(uint64_t));
|
||||
|
||||
|
||||
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->addr, pkt->size);
|
||||
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());
|
||||
|
||||
switch(daddr) {
|
||||
case TSDEV_PC_WSBA0:
|
||||
|
@ -143,7 +143,7 @@ TsunamiPChip::read(Packet *pkt)
|
|||
default:
|
||||
panic("Default in PChip Read reached reading 0x%x\n", daddr);
|
||||
}
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
|
||||
}
|
||||
|
@ -153,13 +153,13 @@ TsunamiPChip::write(Packet *pkt)
|
|||
{
|
||||
pkt->time += pioDelay;
|
||||
|
||||
assert(pkt->result == Unknown);
|
||||
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize);
|
||||
Addr daddr = (pkt->addr - pioAddr) >> 6;
|
||||
assert(pkt->result == Packet::Unknown);
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
Addr daddr = (pkt->getAddr() - pioAddr) >> 6;
|
||||
|
||||
assert(pkt->size == sizeof(uint64_t));
|
||||
assert(pkt->getSize() == sizeof(uint64_t));
|
||||
|
||||
DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->addr, pkt->size);
|
||||
DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize());
|
||||
|
||||
switch(daddr) {
|
||||
case TSDEV_PC_WSBA0:
|
||||
|
@ -224,7 +224,7 @@ TsunamiPChip::write(Packet *pkt)
|
|||
|
||||
} // uint64_t
|
||||
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
|
|
@ -110,12 +110,12 @@ Uart8250::Uart8250(Params *p)
|
|||
Tick
|
||||
Uart8250::read(Packet *pkt)
|
||||
{
|
||||
assert(pkt->result == Unknown);
|
||||
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize);
|
||||
assert(pkt->size == 1);
|
||||
assert(pkt->result == Packet::Unknown);
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
assert(pkt->getSize() == 1);
|
||||
|
||||
pkt->time += pioDelay;
|
||||
Addr daddr = pkt->addr - pioAddr;
|
||||
Addr daddr = pkt->getAddr() - pioAddr;
|
||||
pkt->allocate();
|
||||
|
||||
DPRINTF(Uart, " read register %#x\n", daddr);
|
||||
|
@ -186,7 +186,7 @@ Uart8250::read(Packet *pkt)
|
|||
/* uint32_t d32 = *data;
|
||||
DPRINTF(Uart, "Register read to register %#x returned %#x\n", daddr, d32);
|
||||
*/
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
@ -194,12 +194,12 @@ Tick
|
|||
Uart8250::write(Packet *pkt)
|
||||
{
|
||||
|
||||
assert(pkt->result == Unknown);
|
||||
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize);
|
||||
assert(pkt->size == 1);
|
||||
assert(pkt->result == Packet::Unknown);
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
assert(pkt->getSize() == 1);
|
||||
|
||||
pkt->time += pioDelay;
|
||||
Addr daddr = pkt->addr - pioAddr;
|
||||
Addr daddr = pkt->getAddr() - pioAddr;
|
||||
|
||||
DPRINTF(Uart, " write register %#x value %#x\n", daddr, pkt->get<uint8_t>());
|
||||
|
||||
|
@ -264,7 +264,7 @@ Uart8250::write(Packet *pkt)
|
|||
panic("Tried to access a UART port that doesn't exist\n");
|
||||
break;
|
||||
}
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,18 +55,22 @@ Bus::init()
|
|||
}
|
||||
|
||||
|
||||
/** Function called by the port when the bus is recieving a Timing
|
||||
/** Function called by the port when the bus is receiving a Timing
|
||||
* transaction.*/
|
||||
bool
|
||||
Bus::recvTiming(Packet *pkt)
|
||||
{
|
||||
Port *port;
|
||||
if (pkt->dest == Packet::Broadcast) {
|
||||
port = findPort(pkt->addr, pkt->src);
|
||||
DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n",
|
||||
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
|
||||
|
||||
short dest = pkt->getDest();
|
||||
if (dest == Packet::Broadcast) {
|
||||
port = findPort(pkt->getAddr(), pkt->getSrc());
|
||||
} else {
|
||||
assert(pkt->dest >= 0 && pkt->dest < interfaces.size());
|
||||
assert(pkt->dest != pkt->src); // catch infinite loops
|
||||
port = interfaces[pkt->dest];
|
||||
assert(dest >= 0 && dest < interfaces.size());
|
||||
assert(dest != pkt->getSrc()); // catch infinite loops
|
||||
port = interfaces[dest];
|
||||
}
|
||||
return port->sendTiming(pkt);
|
||||
}
|
||||
|
@ -84,7 +88,7 @@ Bus::findPort(Addr addr, int id)
|
|||
if (portList[i].range == addr) {
|
||||
dest_id = portList[i].portId;
|
||||
found = true;
|
||||
DPRINTF(Bus, "Found Addr: %llx on device %d\n", addr, dest_id);
|
||||
DPRINTF(Bus, " found addr 0x%llx on device %d\n", addr, dest_id);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
@ -97,33 +101,37 @@ Bus::findPort(Addr addr, int id)
|
|||
return interfaces[dest_id];
|
||||
}
|
||||
|
||||
/** Function called by the port when the bus is recieving a Atomic
|
||||
/** Function called by the port when the bus is receiving a Atomic
|
||||
* transaction.*/
|
||||
Tick
|
||||
Bus::recvAtomic(Packet *pkt)
|
||||
{
|
||||
assert(pkt->dest == Packet::Broadcast);
|
||||
return findPort(pkt->addr, pkt->src)->sendAtomic(pkt);
|
||||
DPRINTF(Bus, "recvAtomic: packet src %d dest %d addr 0x%x cmd %s\n",
|
||||
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
|
||||
assert(pkt->getDest() == Packet::Broadcast);
|
||||
return findPort(pkt->getAddr(), pkt->getSrc())->sendAtomic(pkt);
|
||||
}
|
||||
|
||||
/** Function called by the port when the bus is recieving a Functional
|
||||
/** Function called by the port when the bus is receiving a Functional
|
||||
* transaction.*/
|
||||
void
|
||||
Bus::recvFunctional(Packet *pkt)
|
||||
{
|
||||
assert(pkt->dest == Packet::Broadcast);
|
||||
findPort(pkt->addr, pkt->src)->sendFunctional(pkt);
|
||||
DPRINTF(Bus, "recvFunctional: packet src %d dest %d addr 0x%x cmd %s\n",
|
||||
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
|
||||
assert(pkt->getDest() == Packet::Broadcast);
|
||||
findPort(pkt->getAddr(), pkt->getSrc())->sendFunctional(pkt);
|
||||
}
|
||||
|
||||
/** Function called by the port when the bus is recieving a status change.*/
|
||||
/** Function called by the port when the bus is receiving a status change.*/
|
||||
void
|
||||
Bus::recvStatusChange(Port::Status status, int id)
|
||||
{
|
||||
DPRINTF(Bus, "Bus %d recieved status change from device id %d\n",
|
||||
busId, id);
|
||||
assert(status == Port::RangeChange &&
|
||||
"The other statuses need to be implemented.");
|
||||
|
||||
DPRINTF(Bus, "received RangeChange from device id %d\n", id);
|
||||
|
||||
assert(id < interfaces.size() && id >= 0);
|
||||
int x;
|
||||
Port *port = interfaces[id];
|
||||
|
@ -149,8 +157,8 @@ Bus::recvStatusChange(Port::Status status, int id)
|
|||
dm.portId = id;
|
||||
dm.range = *iter;
|
||||
|
||||
DPRINTF(MMU, "Adding range %llx - %llx for id %d\n", dm.range.start,
|
||||
dm.range.end, id);
|
||||
DPRINTF(Bus, "Adding range %llx - %llx for id %d\n",
|
||||
dm.range.start, dm.range.end, id);
|
||||
portList.push_back(dm);
|
||||
}
|
||||
DPRINTF(MMU, "port list has %d entries\n", portList.size());
|
||||
|
@ -170,13 +178,12 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id)
|
|||
resp.clear();
|
||||
snoop.clear();
|
||||
|
||||
DPRINTF(Bus, "Bus id %d recieved address range request returning\n",
|
||||
busId);
|
||||
DPRINTF(Bus, "received address range request, returning:\n");
|
||||
for (portIter = portList.begin(); portIter != portList.end(); portIter++) {
|
||||
if (portIter->portId != id) {
|
||||
resp.push_back(portIter->range);
|
||||
DPRINTF(Bus, "-- %#llX : %#llX\n", portIter->range.start,
|
||||
portIter->range.end);
|
||||
DPRINTF(Bus, " -- %#llX : %#llX\n",
|
||||
portIter->range.start, portIter->range.end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,17 +109,17 @@ class Bus : public MemObject
|
|||
/** When reciving a timing request from the peer port (at id),
|
||||
pass it to the bus. */
|
||||
virtual bool recvTiming(Packet *pkt)
|
||||
{ pkt->src = id; return bus->recvTiming(pkt); }
|
||||
{ pkt->setSrc(id); return bus->recvTiming(pkt); }
|
||||
|
||||
/** When reciving a Atomic requestfrom the peer port (at id),
|
||||
pass it to the bus. */
|
||||
virtual Tick recvAtomic(Packet *pkt)
|
||||
{ pkt->src = id; return bus->recvAtomic(pkt); }
|
||||
{ pkt->setSrc(id); return bus->recvAtomic(pkt); }
|
||||
|
||||
/** When reciving a Functional requestfrom the peer port (at id),
|
||||
pass it to the bus. */
|
||||
virtual void recvFunctional(Packet *pkt)
|
||||
{ pkt->src = id; bus->recvFunctional(pkt); }
|
||||
{ pkt->setSrc(id); bus->recvFunctional(pkt); }
|
||||
|
||||
/** When reciving a status changefrom the peer port (at id),
|
||||
pass it to the bus. */
|
||||
|
|
|
@ -34,11 +34,31 @@
|
|||
#include "base/misc.hh"
|
||||
#include "mem/packet.hh"
|
||||
|
||||
static const std::string ReadReqString("ReadReq");
|
||||
static const std::string WriteReqString("WriteReq");
|
||||
static const std::string WriteReqNoAckString("WriteReqNoAck");
|
||||
static const std::string ReadRespString("ReadResp");
|
||||
static const std::string WriteRespString("WriteResp");
|
||||
static const std::string OtherCmdString("<other>");
|
||||
|
||||
const std::string &
|
||||
Packet::cmdString() const
|
||||
{
|
||||
switch (cmd) {
|
||||
case ReadReq: return ReadReqString;
|
||||
case WriteReq: return WriteReqString;
|
||||
case WriteReqNoAck: return WriteReqNoAckString;
|
||||
case ReadResp: return ReadRespString;
|
||||
case WriteResp: return WriteRespString;
|
||||
default: return OtherCmdString;
|
||||
}
|
||||
}
|
||||
|
||||
/** delete the data pointed to in the data pointer. Ok to call to matter how
|
||||
* data was allocted. */
|
||||
void
|
||||
Packet::deleteData() {
|
||||
Packet::deleteData()
|
||||
{
|
||||
assert(staticData || dynamicData);
|
||||
if (staticData)
|
||||
return;
|
||||
|
@ -51,22 +71,24 @@ Packet::deleteData() {
|
|||
|
||||
/** If there isn't data in the packet, allocate some. */
|
||||
void
|
||||
Packet::allocate() {
|
||||
Packet::allocate()
|
||||
{
|
||||
if (data)
|
||||
return;
|
||||
assert(!staticData);
|
||||
dynamicData = true;
|
||||
arrayData = true;
|
||||
data = new uint8_t[size];
|
||||
data = new uint8_t[getSize()];
|
||||
}
|
||||
|
||||
/** Do the packet modify the same addresses. */
|
||||
bool
|
||||
Packet::intersect(Packet *p) {
|
||||
Addr s1 = addr;
|
||||
Addr e1 = addr + size;
|
||||
Addr s2 = p->addr;
|
||||
Addr e2 = p->addr + p->size;
|
||||
Packet::intersect(Packet *p)
|
||||
{
|
||||
Addr s1 = getAddr();
|
||||
Addr e1 = getAddr() + getSize();
|
||||
Addr s2 = p->getAddr();
|
||||
Addr e2 = p->getAddr() + p->getSize();
|
||||
|
||||
if (s1 >= s2 && s1 < e2)
|
||||
return true;
|
||||
|
@ -77,7 +99,8 @@ Packet::intersect(Packet *p) {
|
|||
|
||||
/** Minimally reset a packet so something like simple cpu can reuse it. */
|
||||
void
|
||||
Packet::reset() {
|
||||
Packet::reset()
|
||||
{
|
||||
result = Unknown;
|
||||
if (dynamicData) {
|
||||
deleteData();
|
||||
|
@ -88,7 +111,8 @@ Packet::reset() {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool fixPacket(Packet *func, Packet *timing)
|
||||
{ panic("Need to implement!"); }
|
||||
bool
|
||||
fixPacket(Packet *func, Packet *timing)
|
||||
{
|
||||
panic("Need to implement!");
|
||||
}
|
||||
|
|
|
@ -43,24 +43,6 @@ struct Packet;
|
|||
typedef Packet* PacketPtr;
|
||||
typedef uint8_t* PacketDataPtr;
|
||||
|
||||
/** List of all commands associated with a packet. */
|
||||
enum Command
|
||||
{
|
||||
Read,
|
||||
Write
|
||||
};
|
||||
|
||||
/** The result of a particular pakets request. */
|
||||
enum PacketResult
|
||||
{
|
||||
Success,
|
||||
BadAddress,
|
||||
Unknown
|
||||
};
|
||||
|
||||
class SenderState{};
|
||||
class Coherence{};
|
||||
|
||||
/**
|
||||
* A Packet is the structure to handle requests between two levels
|
||||
* of the memory system. The Request is a global object that trancends
|
||||
|
@ -74,7 +56,7 @@ class Coherence{};
|
|||
* Packets are assumed to be returned in the case of a single response. If
|
||||
* the transaction has no response, then the consumer will delete the packet.
|
||||
*/
|
||||
struct Packet
|
||||
class Packet
|
||||
{
|
||||
private:
|
||||
/** A pointer to the data being transfered. It can be differnt sizes
|
||||
|
@ -95,57 +77,132 @@ struct Packet
|
|||
bool arrayData;
|
||||
|
||||
|
||||
public:
|
||||
/** The address of the request, could be virtual or physical (depending on
|
||||
cache configurations). */
|
||||
Addr addr;
|
||||
|
||||
/** Flag structure to hold flags for this particular packet */
|
||||
uint64_t flags;
|
||||
|
||||
/** A pointer to the overall request. */
|
||||
RequestPtr req;
|
||||
|
||||
/** A virtual base opaque structure used to hold
|
||||
coherence status messages. */
|
||||
Coherence *coherence; // virtual base opaque,
|
||||
// assert(dynamic_cast<Foo>) etc.
|
||||
|
||||
/** A virtual base opaque structure used to hold the senders state. */
|
||||
void *senderState; // virtual base opaque,
|
||||
// assert(dynamic_cast<Foo>) etc.
|
||||
|
||||
/** Indicates the size of the request. */
|
||||
int size;
|
||||
|
||||
/** A index of the source of the transaction. */
|
||||
short src;
|
||||
|
||||
static const short Broadcast = -1;
|
||||
|
||||
/** A index to the destination of the transaction. */
|
||||
short dest;
|
||||
|
||||
bool addrValid;
|
||||
bool sizeValid;
|
||||
bool srcValid;
|
||||
|
||||
public:
|
||||
|
||||
static const short Broadcast = -1;
|
||||
|
||||
/** A pointer to the overall request. */
|
||||
RequestPtr req;
|
||||
|
||||
class CoherenceState {
|
||||
public:
|
||||
virtual ~CoherenceState() {}
|
||||
};
|
||||
|
||||
/** A virtual base opaque structure used to hold
|
||||
coherence status messages. */
|
||||
CoherenceState *coherence; // virtual base opaque,
|
||||
// assert(dynamic_cast<Foo>) etc.
|
||||
|
||||
class SenderState {
|
||||
public:
|
||||
virtual ~SenderState() {}
|
||||
};
|
||||
|
||||
/** A virtual base opaque structure used to hold the senders state. */
|
||||
SenderState *senderState; // virtual base opaque,
|
||||
// assert(dynamic_cast<Foo>) etc.
|
||||
|
||||
private:
|
||||
/** List of command attributes. */
|
||||
enum CommandAttribute
|
||||
{
|
||||
IsRead = 1 << 0,
|
||||
IsWrite = 1 << 1,
|
||||
IsPrefetch = 1 << 2,
|
||||
IsInvalidate = 1 << 3,
|
||||
IsRequest = 1 << 4,
|
||||
IsResponse = 1 << 5,
|
||||
NeedsResponse = 1 << 6,
|
||||
};
|
||||
|
||||
public:
|
||||
/** List of all commands associated with a packet. */
|
||||
enum Command
|
||||
{
|
||||
ReadReq = IsRead | IsRequest | NeedsResponse,
|
||||
WriteReq = IsWrite | IsRequest | NeedsResponse,
|
||||
WriteReqNoAck = IsWrite | IsRequest,
|
||||
ReadResp = IsRead | IsResponse,
|
||||
WriteResp = IsWrite | IsResponse
|
||||
};
|
||||
|
||||
const std::string &cmdString() const;
|
||||
|
||||
/** The command of the transaction. */
|
||||
Command cmd;
|
||||
|
||||
bool isRead() { return (cmd & IsRead) != 0; }
|
||||
bool isRequest() { return (cmd & IsRequest) != 0; }
|
||||
bool isResponse() { return (cmd & IsResponse) != 0; }
|
||||
bool needsResponse() { return (cmd & NeedsResponse) != 0; }
|
||||
|
||||
void makeTimingResponse() {
|
||||
assert(needsResponse());
|
||||
int icmd = (int)cmd;
|
||||
icmd &= ~(IsRequest | NeedsResponse);
|
||||
icmd |= IsResponse;
|
||||
cmd = (Command)icmd;
|
||||
dest = src;
|
||||
srcValid = false;
|
||||
}
|
||||
|
||||
/** The time this request was responded to. Used to calculate latencies. */
|
||||
Tick time;
|
||||
|
||||
/** The result of a particular packets request. */
|
||||
enum Result
|
||||
{
|
||||
Success,
|
||||
BadAddress,
|
||||
Unknown
|
||||
};
|
||||
|
||||
/** The result of the packet transaction. */
|
||||
PacketResult result;
|
||||
Result result;
|
||||
|
||||
/** Accessor function that returns the source index of the packet. */
|
||||
short getSrc() const { return src; }
|
||||
short getSrc() const { assert(srcValid); return src; }
|
||||
void setSrc(short _src) { src = _src; srcValid = true; }
|
||||
|
||||
/** Accessor function that returns the destination index of
|
||||
the packet. */
|
||||
short getDest() const { return dest; }
|
||||
void setDest(short _dest) { dest = _dest; }
|
||||
|
||||
Packet()
|
||||
Addr getAddr() const { assert(addrValid); return addr; }
|
||||
void setAddr(Addr _addr) { addr = _addr; addrValid = true; }
|
||||
|
||||
int getSize() const { assert(sizeValid); return size; }
|
||||
void setSize(int _size) { size = _size; sizeValid = true; }
|
||||
|
||||
|
||||
Packet(Request *_req, Command _cmd, short _dest)
|
||||
: data(NULL), staticData(false), dynamicData(false), arrayData(false),
|
||||
addr(_req->paddr), size(_req->size), dest(_dest),
|
||||
addrValid(_req->validPaddr), sizeValid(_req->validSize),
|
||||
srcValid(false),
|
||||
req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
|
||||
time(curTick), result(Unknown)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
~Packet()
|
||||
{ deleteData(); }
|
||||
|
@ -154,6 +211,11 @@ struct Packet
|
|||
/** Minimally reset a packet so something like simple cpu can reuse it. */
|
||||
void reset();
|
||||
|
||||
void reinitFromRequest() {
|
||||
if (req->validPaddr) setAddr(req->paddr);
|
||||
if (req->validSize) setSize(req->size);
|
||||
}
|
||||
|
||||
/** Set the data pointer to the following value that should not be freed. */
|
||||
template <typename T>
|
||||
void dataStatic(T *p);
|
||||
|
|
|
@ -128,7 +128,7 @@ PhysicalMemory::doTimingAccess (Packet *pkt, MemoryPort* memoryPort)
|
|||
doFunctionalAccess(pkt);
|
||||
|
||||
// turn packet around to go back to requester
|
||||
pkt->dest = pkt->src;
|
||||
pkt->makeTimingResponse();
|
||||
MemResponseEvent* response = new MemResponseEvent(pkt, memoryPort);
|
||||
response->schedule(curTick + lat);
|
||||
|
||||
|
@ -146,16 +146,18 @@ PhysicalMemory::doAtomicAccess(Packet *pkt)
|
|||
void
|
||||
PhysicalMemory::doFunctionalAccess(Packet *pkt)
|
||||
{
|
||||
assert(pkt->addr + pkt->size < pmem_size);
|
||||
assert(pkt->getAddr() + pkt->getSize() < pmem_size);
|
||||
|
||||
switch (pkt->cmd) {
|
||||
case Read:
|
||||
memcpy(pkt->getPtr<uint8_t>(), pmem_addr + pkt->addr - base_addr,
|
||||
pkt->size);
|
||||
case Packet::ReadReq:
|
||||
memcpy(pkt->getPtr<uint8_t>(),
|
||||
pmem_addr + pkt->getAddr() - base_addr,
|
||||
pkt->getSize());
|
||||
break;
|
||||
case Write:
|
||||
memcpy(pmem_addr + pkt->addr - base_addr, pkt->getPtr<uint8_t>(),
|
||||
pkt->size);
|
||||
case Packet::WriteReq:
|
||||
memcpy(pmem_addr + pkt->getAddr() - base_addr,
|
||||
pkt->getPtr<uint8_t>(),
|
||||
pkt->getSize());
|
||||
// temporary hack: will need to add real LL/SC implementation
|
||||
// for cacheless systems later.
|
||||
if (pkt->req->getFlags() & LOCKED) {
|
||||
|
@ -166,7 +168,7 @@ PhysicalMemory::doFunctionalAccess(Packet *pkt)
|
|||
panic("unimplemented");
|
||||
}
|
||||
|
||||
pkt->result = Success;
|
||||
pkt->result = Packet::Success;
|
||||
}
|
||||
|
||||
Port *
|
||||
|
|
|
@ -35,18 +35,16 @@
|
|||
#include "mem/port.hh"
|
||||
|
||||
void
|
||||
Port::blobHelper(Addr addr, uint8_t *p, int size, Command cmd)
|
||||
Port::blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd)
|
||||
{
|
||||
Request req(false);
|
||||
Packet pkt;
|
||||
pkt.req = &req;
|
||||
pkt.cmd = cmd;
|
||||
pkt.dest = Packet::Broadcast;
|
||||
Packet pkt(&req, cmd, Packet::Broadcast);
|
||||
|
||||
for (ChunkGenerator gen(addr, size, peerBlockSize());
|
||||
!gen.done(); gen.next()) {
|
||||
req.setPaddr(pkt.addr = gen.addr());
|
||||
req.setSize(pkt.size = gen.size());
|
||||
req.setPaddr(gen.addr());
|
||||
req.setSize(gen.size());
|
||||
pkt.reinitFromRequest();
|
||||
pkt.dataStatic(p);
|
||||
sendFunctional(&pkt);
|
||||
p += gen.size();
|
||||
|
@ -56,13 +54,13 @@ Port::blobHelper(Addr addr, uint8_t *p, int size, Command cmd)
|
|||
void
|
||||
Port::writeBlob(Addr addr, uint8_t *p, int size)
|
||||
{
|
||||
blobHelper(addr, p, size, Write);
|
||||
blobHelper(addr, p, size, Packet::WriteReq);
|
||||
}
|
||||
|
||||
void
|
||||
Port::readBlob(Addr addr, uint8_t *p, int size)
|
||||
{
|
||||
blobHelper(addr, p, size, Read);
|
||||
blobHelper(addr, p, size, Packet::ReadReq);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -72,7 +70,7 @@ Port::memsetBlob(Addr addr, uint8_t val, int size)
|
|||
uint8_t *buf = new uint8_t[size];
|
||||
|
||||
memset(buf, val, size);
|
||||
blobHelper(addr, buf, size, Write);
|
||||
blobHelper(addr, buf, size, Packet::WriteReq);
|
||||
|
||||
delete [] buf;
|
||||
}
|
||||
|
|
|
@ -232,7 +232,7 @@ class Port
|
|||
|
||||
/** Internal helper function for read/writeBlob().
|
||||
*/
|
||||
void blobHelper(Addr addr, uint8_t *p, int size, Command cmd);
|
||||
void blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd);
|
||||
};
|
||||
|
||||
/** A simple functional port that is only meant for one way communication to
|
||||
|
|
|
@ -195,6 +195,7 @@ class Request
|
|||
/** Accesor function for pc.*/
|
||||
void setPC(Addr _pc);
|
||||
|
||||
friend class Packet;
|
||||
};
|
||||
|
||||
#endif // __MEM_REQUEST_HH__
|
||||
|
|
Loading…
Reference in a new issue