// @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);
}
// 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>();
}
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();
Fault fault = cpuXC->translateInstReq(ifetch_req);
if (fault == NoFault) {
- ifetch_pkt->addr = ifetch_req->getPaddr();
+ ifetch_pkt->reinitFromRequest();
}
return fault;
// 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;
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;
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) {
{
// 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;
* 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)
/* 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>());
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;
}
{
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):
panic("Unknown 64bit access, %#x\n", daddr);
}
- pkt->result = Success;
+ pkt->result = Packet::Success;
return pioDelay;
}
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;
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;
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;
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;
}
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;
}
switch (reg_type) {
case BMI_BLOCK:
if (!bm_enabled) {
- pkt->result = Success;
+ pkt->result = Packet::Success;
return pioDelay;
}
// 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);
// 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>();
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:
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;
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;
}
void
PioPort::SendEvent::process()
{
- if (port->Port::sendTiming(packet) == Success)
+ if (port->Port::sendTiming(packet))
return;
port->transmitList.push_back(packet);
{
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()
{
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;
delete pkt;
}
- return Success;
+ return Packet::Success;
}
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);
transmitList.pop_front();
return pkt;
}
+
+
void
-DmaPort::dmaAction(Command cmd, Addr addr, int size, Event *event,
- uint8_t *data)
+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);
}
/* 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--;
};
-struct DmaReqState
+struct DmaReqState : public Packet::SenderState
{
Event *completionEvent;
bool final;
public:
DmaPort(DmaDevice *dev, Platform *p);
- void dmaAction(Command cmd, Addr addr, int size, Event *event,
- uint8_t *data = NULL);
+ void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
+ uint8_t *data = NULL);
bool dmaPending() { return pendingCount > 0; }
/** 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.
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(); }
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):
default:
panic("invalid access size(?) for PCI configspace!\n");
}
- pkt->result = Success;
+ pkt->result = Packet::Success;
return pioDelay;
}
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;
}
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
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;
DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n",
daddr, reg, reg);
- pkt->result = Success;
+ pkt->result = Packet::Success;
return pioDelay;
}
{
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;
} else {
panic("Invalid Request Size");
}
- pkt->result = Success;
+ pkt->result = Packet::Success;
return pioDelay;
}
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;
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);
default:
panic("invalid access size(?) for PCI configspace!\n");
}
- pkt->result = Success;
+ pkt->result = Packet::Success;
return pioDelay;
}
{
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;
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;
default:
panic("invalid pci config write size\n");
}
- pkt->result = Success;
+ pkt->result = Packet::Success;
return pioDelay;
}
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;
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;
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
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;
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);
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)
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;
}
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;
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;
}
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:
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;
}
{
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:
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;
}
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:
default:
panic("Default in PChip Read reached reading 0x%x\n", daddr);
}
- pkt->result = Success;
+ pkt->result = Packet::Success;
return pioDelay;
}
{
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:
} // uint64_t
- pkt->result = Success;
+ pkt->result = Packet::Success;
return pioDelay;
}
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);
/* 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;
}
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>());
panic("Tried to access a UART port that doesn't exist\n");
break;
}
- pkt->result = Success;
+ pkt->result = Packet::Success;
return pioDelay;
}
}
-/** 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);
}
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++;
}
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];
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());
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);
}
}
}
/** 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. */
#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;
/** 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;
/** Minimally reset a packet so something like simple cpu can reuse it. */
void
-Packet::reset() {
+Packet::reset()
+{
result = Unknown;
if (dynamicData) {
deleteData();
}
-
-
-bool fixPacket(Packet *func, Packet *timing)
-{ panic("Need to implement!"); }
+bool
+fixPacket(Packet *func, Packet *timing)
+{
+ panic("Need to implement!");
+}
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
* 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
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;
+ /** Indicates the size of the request. */
+ int size;
+
+ /** A index of the source of the transaction. */
+ short src;
+
+ /** 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. */
- Coherence *coherence; // virtual base opaque,
+ CoherenceState *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;
+ class SenderState {
+ public:
+ virtual ~SenderState() {}
+ };
- /** A index of the source of the transaction. */
- short src;
+ /** A virtual base opaque structure used to hold the senders state. */
+ SenderState *senderState; // virtual base opaque,
+ // assert(dynamic_cast<Foo>) etc.
- static const short Broadcast = -1;
+ 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,
+ };
- /** A index to the destination of the transaction. */
- short dest;
+ 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; }
+
+ 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()
+
+ 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(); }
/** 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);
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);
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) {
panic("unimplemented");
}
- pkt->result = Success;
+ pkt->result = Packet::Success;
}
Port *
#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();
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
uint8_t *buf = new uint8_t[size];
memset(buf, val, size);
- blobHelper(addr, buf, size, Write);
+ blobHelper(addr, buf, size, Packet::WriteReq);
delete [] buf;
}
/** 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
/** Accesor function for pc.*/
void setPC(Addr _pc);
+ friend class Packet;
};
#endif // __MEM_REQUEST_HH__