Minor further cleanup & commenting of Packet class.
src/cpu/simple/atomic.cc: Make common ifetch setup based on Request rather than Packet. Packet::reset() no longer a separate function. sendAtomic() returns latency, not absolute tick. src/cpu/simple/atomic.hh: sendAtomic returns latency, not absolute tick. src/cpu/simple/base.cc: src/cpu/simple/base.hh: src/cpu/simple/timing.cc: Make common ifetch setup based on Request rather than Packet. src/dev/alpha_console.cc: src/dev/ide_ctrl.cc: src/dev/io_device.cc: 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/physical.cc: Get rid of redundant Packet time field. src/mem/packet.cc: Eliminate reset() method. src/mem/packet.hh: Fold reset() function into reinitFromRequest()... it was only ever called together with that function. Get rid of redundant time field. Cleanup/add comments. src/mem/port.hh: Document in comment that sendAtomic returns latency, not absolute tick. --HG-- extra : convert_revision : 0252f1a294043ca3ed58f437232ad24fc0733e0c
This commit is contained in:
parent
0e5db091e9
commit
91e3aa6295
20 changed files with 120 additions and 140 deletions
|
@ -250,10 +250,9 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
|
||||||
|
|
||||||
// Now do the access.
|
// Now do the access.
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
data_read_pkt->reset();
|
|
||||||
data_read_pkt->reinitFromRequest();
|
data_read_pkt->reinitFromRequest();
|
||||||
|
|
||||||
dcache_complete = dcachePort.sendAtomic(data_read_pkt);
|
dcache_latency = dcachePort.sendAtomic(data_read_pkt);
|
||||||
dcache_access = true;
|
dcache_access = true;
|
||||||
|
|
||||||
assert(data_read_pkt->result == Packet::Success);
|
assert(data_read_pkt->result == Packet::Success);
|
||||||
|
@ -329,12 +328,11 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
|
||||||
|
|
||||||
// Now do the access.
|
// Now do the access.
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
data_write_pkt->reset();
|
|
||||||
data = htog(data);
|
data = htog(data);
|
||||||
data_write_pkt->dataStatic(&data);
|
|
||||||
data_write_pkt->reinitFromRequest();
|
data_write_pkt->reinitFromRequest();
|
||||||
|
data_write_pkt->dataStatic(&data);
|
||||||
|
|
||||||
dcache_complete = dcachePort.sendAtomic(data_write_pkt);
|
dcache_latency = dcachePort.sendAtomic(data_write_pkt);
|
||||||
dcache_access = true;
|
dcache_access = true;
|
||||||
|
|
||||||
assert(data_write_pkt->result == Packet::Success);
|
assert(data_write_pkt->result == Packet::Success);
|
||||||
|
@ -411,11 +409,12 @@ AtomicSimpleCPU::tick()
|
||||||
checkForInterrupts();
|
checkForInterrupts();
|
||||||
|
|
||||||
ifetch_req->resetMin();
|
ifetch_req->resetMin();
|
||||||
ifetch_pkt->reset();
|
Fault fault = setupFetchRequest(ifetch_req);
|
||||||
Fault fault = setupFetchPacket(ifetch_pkt);
|
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
Tick icache_complete = icachePort.sendAtomic(ifetch_pkt);
|
ifetch_pkt->reinitFromRequest();
|
||||||
|
|
||||||
|
Tick icache_latency = icachePort.sendAtomic(ifetch_pkt);
|
||||||
// ifetch_req is initialized to read the instruction directly
|
// ifetch_req is initialized to read the instruction directly
|
||||||
// into the CPU object's inst field.
|
// into the CPU object's inst field.
|
||||||
|
|
||||||
|
@ -430,9 +429,9 @@ AtomicSimpleCPU::tick()
|
||||||
// cycle time. If not, the next tick event may get
|
// cycle time. If not, the next tick event may get
|
||||||
// scheduled at a non-integer multiple of the CPU
|
// scheduled at a non-integer multiple of the CPU
|
||||||
// cycle time.
|
// cycle time.
|
||||||
Tick icache_stall = icache_complete - curTick - cycles(1);
|
Tick icache_stall = icache_latency - cycles(1);
|
||||||
Tick dcache_stall =
|
Tick dcache_stall =
|
||||||
dcache_access ? dcache_complete - curTick - cycles(1) : 0;
|
dcache_access ? dcache_latency - cycles(1) : 0;
|
||||||
latency += icache_stall + dcache_stall;
|
latency += icache_stall + dcache_stall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU
|
||||||
Packet *data_write_pkt;
|
Packet *data_write_pkt;
|
||||||
|
|
||||||
bool dcache_access;
|
bool dcache_access;
|
||||||
Tick dcache_complete;
|
Tick dcache_latency;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -351,29 +351,21 @@ BaseSimpleCPU::checkForInterrupts()
|
||||||
|
|
||||||
|
|
||||||
Fault
|
Fault
|
||||||
BaseSimpleCPU::setupFetchPacket(Packet *ifetch_pkt)
|
BaseSimpleCPU::setupFetchRequest(Request *req)
|
||||||
{
|
{
|
||||||
// Try to fetch an instruction
|
|
||||||
|
|
||||||
// set up memory request for instruction fetch
|
// set up memory request for instruction fetch
|
||||||
|
|
||||||
DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(),
|
DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(),
|
||||||
cpuXC->readNextPC(),cpuXC->readNextNPC());
|
cpuXC->readNextPC(),cpuXC->readNextNPC());
|
||||||
|
|
||||||
Request *ifetch_req = ifetch_pkt->req;
|
req->setVaddr(cpuXC->readPC() & ~3);
|
||||||
ifetch_req->setVaddr(cpuXC->readPC() & ~3);
|
req->setTime(curTick);
|
||||||
ifetch_req->setTime(curTick);
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
ifetch_req->setFlags((cpuXC->readPC() & 1) ? PHYSICAL : 0);
|
req->setFlags((cpuXC->readPC() & 1) ? PHYSICAL : 0);
|
||||||
#else
|
#else
|
||||||
ifetch_req->setFlags(0);
|
req->setFlags(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Fault fault = cpuXC->translateInstReq(ifetch_req);
|
Fault fault = cpuXC->translateInstReq(req);
|
||||||
|
|
||||||
if (fault == NoFault) {
|
|
||||||
ifetch_pkt->reinitFromRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ class BaseSimpleCPU : public BaseCPU
|
||||||
StaticInstPtr curStaticInst;
|
StaticInstPtr curStaticInst;
|
||||||
|
|
||||||
void checkForInterrupts();
|
void checkForInterrupts();
|
||||||
Fault setupFetchPacket(Packet *ifetch_pkt);
|
Fault setupFetchRequest(Request *req);
|
||||||
void preExecute();
|
void preExecute();
|
||||||
void postExecute();
|
void postExecute();
|
||||||
void advancePC(Fault fault);
|
void advancePC(Fault fault);
|
||||||
|
|
|
@ -342,11 +342,11 @@ TimingSimpleCPU::fetch()
|
||||||
|
|
||||||
Request *ifetch_req = new Request(true);
|
Request *ifetch_req = new Request(true);
|
||||||
ifetch_req->setSize(sizeof(MachInst));
|
ifetch_req->setSize(sizeof(MachInst));
|
||||||
|
Fault fault = setupFetchRequest(ifetch_req);
|
||||||
|
|
||||||
ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
|
ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
|
||||||
ifetch_pkt->dataStatic(&inst);
|
ifetch_pkt->dataStatic(&inst);
|
||||||
|
|
||||||
Fault fault = setupFetchPacket(ifetch_pkt);
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
if (!icachePort.sendTiming(ifetch_pkt)) {
|
if (!icachePort.sendTiming(ifetch_pkt)) {
|
||||||
// Need to wait for retry
|
// Need to wait for retry
|
||||||
|
|
|
@ -98,7 +98,6 @@ AlphaConsole::read(Packet *pkt)
|
||||||
assert(pkt->result == Packet::Unknown);
|
assert(pkt->result == Packet::Unknown);
|
||||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||||
|
|
||||||
pkt->time += pioDelay;
|
|
||||||
Addr daddr = pkt->getAddr() - pioAddr;
|
Addr daddr = pkt->getAddr() - pioAddr;
|
||||||
|
|
||||||
pkt->allocate();
|
pkt->allocate();
|
||||||
|
@ -191,8 +190,6 @@ AlphaConsole::read(Packet *pkt)
|
||||||
Tick
|
Tick
|
||||||
AlphaConsole::write(Packet *pkt)
|
AlphaConsole::write(Packet *pkt)
|
||||||
{
|
{
|
||||||
pkt->time += pioDelay;
|
|
||||||
|
|
||||||
assert(pkt->result == Packet::Unknown);
|
assert(pkt->result == Packet::Unknown);
|
||||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||||
Addr daddr = pkt->getAddr() - pioAddr;
|
Addr daddr = pkt->getAddr() - pioAddr;
|
||||||
|
|
|
@ -430,7 +430,6 @@ IdeController::read(Packet *pkt)
|
||||||
IdeRegType reg_type;
|
IdeRegType reg_type;
|
||||||
int disk;
|
int disk;
|
||||||
|
|
||||||
pkt->time += pioDelay;
|
|
||||||
pkt->allocate();
|
pkt->allocate();
|
||||||
if (pkt->getSize() != 1 && pkt->getSize() != 2 && pkt->getSize() !=4)
|
if (pkt->getSize() != 1 && pkt->getSize() != 2 && pkt->getSize() !=4)
|
||||||
panic("Bad IDE read size: %d\n", pkt->getSize());
|
panic("Bad IDE read size: %d\n", pkt->getSize());
|
||||||
|
@ -518,8 +517,6 @@ IdeController::write(Packet *pkt)
|
||||||
int disk;
|
int disk;
|
||||||
uint8_t oldVal, newVal;
|
uint8_t oldVal, newVal;
|
||||||
|
|
||||||
pkt->time += pioDelay;
|
|
||||||
|
|
||||||
parseAddr(pkt->getAddr(), offset, channel, reg_type);
|
parseAddr(pkt->getAddr(), offset, channel, reg_type);
|
||||||
|
|
||||||
if (!io_enabled) {
|
if (!io_enabled) {
|
||||||
|
|
|
@ -80,10 +80,10 @@ PioPort::SendEvent::process()
|
||||||
bool
|
bool
|
||||||
PioPort::recvTiming(Packet *pkt)
|
PioPort::recvTiming(Packet *pkt)
|
||||||
{
|
{
|
||||||
device->recvAtomic(pkt);
|
Tick latency = device->recvAtomic(pkt);
|
||||||
// turn packet around to go back to requester
|
// turn packet around to go back to requester
|
||||||
pkt->makeTimingResponse();
|
pkt->makeTimingResponse();
|
||||||
sendTiming(pkt, pkt->time - pkt->req->getTime());
|
sendTiming(pkt, latency);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,6 @@ IsaFake::read(Packet *pkt)
|
||||||
assert(pkt->result == Packet::Unknown);
|
assert(pkt->result == Packet::Unknown);
|
||||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||||
|
|
||||||
pkt->time += pioDelay;
|
|
||||||
|
|
||||||
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());
|
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());
|
||||||
|
|
||||||
switch (pkt->getSize()) {
|
switch (pkt->getSize()) {
|
||||||
|
@ -80,7 +78,6 @@ IsaFake::read(Packet *pkt)
|
||||||
Tick
|
Tick
|
||||||
IsaFake::write(Packet *pkt)
|
IsaFake::write(Packet *pkt)
|
||||||
{
|
{
|
||||||
pkt->time += pioDelay;
|
|
||||||
DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize());
|
DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize());
|
||||||
pkt->result = Packet::Success;
|
pkt->result = Packet::Success;
|
||||||
return pioDelay;
|
return pioDelay;
|
||||||
|
|
|
@ -492,7 +492,6 @@ NSGigE::read(Packet *pkt)
|
||||||
{
|
{
|
||||||
assert(ioEnable);
|
assert(ioEnable);
|
||||||
|
|
||||||
pkt->time += pioDelay;
|
|
||||||
pkt->allocate();
|
pkt->allocate();
|
||||||
|
|
||||||
//The mask is to give you only the offset into the device register file
|
//The mask is to give you only the offset into the device register file
|
||||||
|
@ -728,8 +727,6 @@ NSGigE::write(Packet *pkt)
|
||||||
DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n",
|
DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n",
|
||||||
daddr, pkt->getAddr(), pkt->getSize());
|
daddr, pkt->getAddr(), pkt->getSize());
|
||||||
|
|
||||||
pkt->time += pioDelay;
|
|
||||||
|
|
||||||
if (daddr > LAST && daddr <= RESERVED) {
|
if (daddr > LAST && daddr <= RESERVED) {
|
||||||
panic("Accessing reserved register");
|
panic("Accessing reserved register");
|
||||||
} else if (daddr > RESERVED && daddr <= 0x3FC) {
|
} else if (daddr > RESERVED && daddr <= 0x3FC) {
|
||||||
|
|
|
@ -99,7 +99,6 @@ PciConfigAll::read(Packet *pkt)
|
||||||
int func = (daddr >> 8) & 0x7;
|
int func = (daddr >> 8) & 0x7;
|
||||||
int reg = daddr & 0xFF;
|
int reg = daddr & 0xFF;
|
||||||
|
|
||||||
pkt->time += pioDelay;
|
|
||||||
pkt->allocate();
|
pkt->allocate();
|
||||||
|
|
||||||
DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt->getAddr(), daddr,
|
DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt->getAddr(), daddr,
|
||||||
|
@ -134,8 +133,6 @@ PciConfigAll::read(Packet *pkt)
|
||||||
Tick
|
Tick
|
||||||
PciConfigAll::write(Packet *pkt)
|
PciConfigAll::write(Packet *pkt)
|
||||||
{
|
{
|
||||||
pkt->time += pioDelay;
|
|
||||||
|
|
||||||
assert(pkt->result == Packet::Unknown);
|
assert(pkt->result == Packet::Unknown);
|
||||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||||
assert(pkt->getSize() == sizeof(uint8_t) || pkt->getSize() == sizeof(uint16_t) ||
|
assert(pkt->getSize() == sizeof(uint8_t) || pkt->getSize() == sizeof(uint16_t) ||
|
||||||
|
|
|
@ -322,7 +322,6 @@ Device::read(Packet *pkt)
|
||||||
Addr index = daddr >> Regs::VirtualShift;
|
Addr index = daddr >> Regs::VirtualShift;
|
||||||
Addr raddr = daddr & Regs::VirtualMask;
|
Addr raddr = daddr & Regs::VirtualMask;
|
||||||
|
|
||||||
pkt->time += pioDelay;
|
|
||||||
pkt->allocate();
|
pkt->allocate();
|
||||||
|
|
||||||
if (!regValid(raddr))
|
if (!regValid(raddr))
|
||||||
|
@ -410,8 +409,6 @@ Device::write(Packet *pkt)
|
||||||
Addr index = daddr >> Regs::VirtualShift;
|
Addr index = daddr >> Regs::VirtualShift;
|
||||||
Addr raddr = daddr & Regs::VirtualMask;
|
Addr raddr = daddr & Regs::VirtualMask;
|
||||||
|
|
||||||
pkt->time += pioDelay;
|
|
||||||
|
|
||||||
if (!regValid(raddr))
|
if (!regValid(raddr))
|
||||||
panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d",
|
panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d",
|
||||||
cpu, daddr, pkt->getAddr(), pkt->getSize());
|
cpu, daddr, pkt->getAddr(), pkt->getSize());
|
||||||
|
|
|
@ -76,7 +76,6 @@ TsunamiCChip::read(Packet *pkt)
|
||||||
assert(pkt->result == Packet::Unknown);
|
assert(pkt->result == Packet::Unknown);
|
||||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||||
|
|
||||||
pkt->time += pioDelay;
|
|
||||||
Addr regnum = (pkt->getAddr() - pioAddr) >> 6;
|
Addr regnum = (pkt->getAddr() - pioAddr) >> 6;
|
||||||
Addr daddr = (pkt->getAddr() - pioAddr);
|
Addr daddr = (pkt->getAddr() - pioAddr);
|
||||||
|
|
||||||
|
@ -182,9 +181,6 @@ TsunamiCChip::read(Packet *pkt)
|
||||||
Tick
|
Tick
|
||||||
TsunamiCChip::write(Packet *pkt)
|
TsunamiCChip::write(Packet *pkt)
|
||||||
{
|
{
|
||||||
pkt->time += pioDelay;
|
|
||||||
|
|
||||||
|
|
||||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||||
Addr daddr = pkt->getAddr() - pioAddr;
|
Addr daddr = pkt->getAddr() - pioAddr;
|
||||||
Addr regnum = (pkt->getAddr() - pioAddr) >> 6 ;
|
Addr regnum = (pkt->getAddr() - pioAddr) >> 6 ;
|
||||||
|
|
|
@ -447,7 +447,6 @@ TsunamiIO::read(Packet *pkt)
|
||||||
assert(pkt->result == Packet::Unknown);
|
assert(pkt->result == Packet::Unknown);
|
||||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||||
|
|
||||||
pkt->time += pioDelay;
|
|
||||||
Addr daddr = pkt->getAddr() - pioAddr;
|
Addr daddr = pkt->getAddr() - pioAddr;
|
||||||
|
|
||||||
DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt->getAddr(),
|
DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt->getAddr(),
|
||||||
|
@ -511,8 +510,6 @@ TsunamiIO::read(Packet *pkt)
|
||||||
Tick
|
Tick
|
||||||
TsunamiIO::write(Packet *pkt)
|
TsunamiIO::write(Packet *pkt)
|
||||||
{
|
{
|
||||||
pkt->time += pioDelay;
|
|
||||||
|
|
||||||
assert(pkt->result == Packet::Unknown);
|
assert(pkt->result == Packet::Unknown);
|
||||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||||
Addr daddr = pkt->getAddr() - pioAddr;
|
Addr daddr = pkt->getAddr() - pioAddr;
|
||||||
|
|
|
@ -70,8 +70,6 @@ TsunamiPChip::read(Packet *pkt)
|
||||||
assert(pkt->result == Packet::Unknown);
|
assert(pkt->result == Packet::Unknown);
|
||||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||||
|
|
||||||
|
|
||||||
pkt->time += pioDelay;
|
|
||||||
pkt->allocate();
|
pkt->allocate();
|
||||||
Addr daddr = (pkt->getAddr() - pioAddr) >> 6;;
|
Addr daddr = (pkt->getAddr() - pioAddr) >> 6;;
|
||||||
assert(pkt->getSize() == sizeof(uint64_t));
|
assert(pkt->getSize() == sizeof(uint64_t));
|
||||||
|
@ -151,8 +149,6 @@ TsunamiPChip::read(Packet *pkt)
|
||||||
Tick
|
Tick
|
||||||
TsunamiPChip::write(Packet *pkt)
|
TsunamiPChip::write(Packet *pkt)
|
||||||
{
|
{
|
||||||
pkt->time += pioDelay;
|
|
||||||
|
|
||||||
assert(pkt->result == Packet::Unknown);
|
assert(pkt->result == Packet::Unknown);
|
||||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||||
Addr daddr = (pkt->getAddr() - pioAddr) >> 6;
|
Addr daddr = (pkt->getAddr() - pioAddr) >> 6;
|
||||||
|
|
|
@ -114,7 +114,6 @@ Uart8250::read(Packet *pkt)
|
||||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||||
assert(pkt->getSize() == 1);
|
assert(pkt->getSize() == 1);
|
||||||
|
|
||||||
pkt->time += pioDelay;
|
|
||||||
Addr daddr = pkt->getAddr() - pioAddr;
|
Addr daddr = pkt->getAddr() - pioAddr;
|
||||||
pkt->allocate();
|
pkt->allocate();
|
||||||
|
|
||||||
|
@ -198,7 +197,6 @@ Uart8250::write(Packet *pkt)
|
||||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||||
assert(pkt->getSize() == 1);
|
assert(pkt->getSize() == 1);
|
||||||
|
|
||||||
pkt->time += pioDelay;
|
|
||||||
Addr daddr = pkt->getAddr() - pioAddr;
|
Addr daddr = pkt->getAddr() - pioAddr;
|
||||||
|
|
||||||
DPRINTF(Uart, " write register %#x value %#x\n", daddr, pkt->get<uint8_t>());
|
DPRINTF(Uart, " write register %#x value %#x\n", daddr, pkt->get<uint8_t>());
|
||||||
|
|
|
@ -97,20 +97,6 @@ Packet::intersect(Packet *p)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Minimally reset a packet so something like simple cpu can reuse it. */
|
|
||||||
void
|
|
||||||
Packet::reset()
|
|
||||||
{
|
|
||||||
result = Unknown;
|
|
||||||
if (dynamicData) {
|
|
||||||
deleteData();
|
|
||||||
dynamicData = false;
|
|
||||||
arrayData = false;
|
|
||||||
time = curTick;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fixPacket(Packet *func, Packet *timing)
|
fixPacket(Packet *func, Packet *timing)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,8 +28,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* Declaration of the Packet Class, a packet is a transaction occuring
|
* Declaration of the Packet class.
|
||||||
* between a single level of the memory heirarchy (ie L1->L2).
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MEM_PACKET_HH__
|
#ifndef __MEM_PACKET_HH__
|
||||||
|
@ -44,81 +43,98 @@ typedef Packet* PacketPtr;
|
||||||
typedef uint8_t* PacketDataPtr;
|
typedef uint8_t* PacketDataPtr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Packet is the structure to handle requests between two levels
|
* A Packet is used to encapsulate a transfer between two objects in
|
||||||
* of the memory system. The Request is a global object that trancends
|
* the memory system (e.g., the L1 and L2 cache). (In contrast, a
|
||||||
* all of the memory heirarchy, but at each levels interface a packet
|
* single Request travels all the way from the requester to the
|
||||||
* is created to transfer data/requests. For example, a request would
|
* ultimate destination and back, possibly being conveyed by several
|
||||||
* be used to initiate a request to go to memory/IOdevices, as the request
|
* different Packets along the way.)
|
||||||
* passes through the memory system several packets will be created. One
|
|
||||||
* will be created to go between the L1 and L2 caches and another to go to
|
|
||||||
* the next level and so forth.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
class Packet
|
class Packet
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/** A pointer to the data being transfered. It can be differnt sizes
|
/** A pointer to the data being transfered. It can be differnt
|
||||||
at each level of the heirarchy so it belongs in the packet,
|
* sizes at each level of the heirarchy so it belongs in the
|
||||||
not request. This may or may not be populated when a responder recieves
|
* packet, not request. This may or may not be populated when a
|
||||||
the packet. If not populated it memory should be allocated.
|
* responder recieves the packet. If not populated it memory
|
||||||
|
* should be allocated.
|
||||||
*/
|
*/
|
||||||
PacketDataPtr data;
|
PacketDataPtr data;
|
||||||
|
|
||||||
/** Is the data pointer set to a value that shouldn't be freed when the
|
/** Is the data pointer set to a value that shouldn't be freed
|
||||||
* packet is destroyed? */
|
* when the packet is destroyed? */
|
||||||
bool staticData;
|
bool staticData;
|
||||||
/** The data pointer points to a value that should be freed when the packet
|
/** The data pointer points to a value that should be freed when
|
||||||
* is destroyed. */
|
* the packet is destroyed. */
|
||||||
bool dynamicData;
|
bool dynamicData;
|
||||||
/** the data pointer points to an array (thus delete [] ) needs to be called
|
/** the data pointer points to an array (thus delete [] ) needs to
|
||||||
* on it rather than simply delete.*/
|
* be called on it rather than simply delete.*/
|
||||||
bool arrayData;
|
bool arrayData;
|
||||||
|
|
||||||
|
|
||||||
/** The address of the request, could be virtual or physical (depending on
|
/** The address of the request. This address could be virtual or
|
||||||
cache configurations). */
|
* physical, depending on the system configuration. */
|
||||||
Addr addr;
|
Addr addr;
|
||||||
|
|
||||||
/** Indicates the size of the request. */
|
/** The size of the request or transfer. */
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
/** A index of the source of the transaction. */
|
/** Device address (e.g., bus ID) of the source of the
|
||||||
|
* transaction. The source is not responsible for setting this
|
||||||
|
* field; it is set implicitly by the interconnect when the
|
||||||
|
* packet * is first sent. */
|
||||||
short src;
|
short src;
|
||||||
|
|
||||||
/** A index to the destination of the transaction. */
|
/** Device address (e.g., bus ID) of the destination of the
|
||||||
|
* transaction. The special value Broadcast indicates that the
|
||||||
|
* packet should be routed based on its address. This field is
|
||||||
|
* initialized in the constructor and is thus always valid
|
||||||
|
* (unlike * addr, size, and src). */
|
||||||
short dest;
|
short dest;
|
||||||
|
|
||||||
|
/** Is the 'addr' field valid? */
|
||||||
bool addrValid;
|
bool addrValid;
|
||||||
|
/** Is the 'size' field valid? */
|
||||||
bool sizeValid;
|
bool sizeValid;
|
||||||
|
/** Is the 'src' field valid? */
|
||||||
bool srcValid;
|
bool srcValid;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/** The special destination address indicating that the packet
|
||||||
|
* should be routed based on its address. */
|
||||||
static const short Broadcast = -1;
|
static const short Broadcast = -1;
|
||||||
|
|
||||||
/** A pointer to the overall request. */
|
/** A pointer to the original request. */
|
||||||
RequestPtr req;
|
RequestPtr req;
|
||||||
|
|
||||||
|
/** A virtual base opaque structure used to hold coherence-related
|
||||||
|
* state. A specific subclass would be derived from this to
|
||||||
|
* carry state specific to a particular coherence protocol. */
|
||||||
class CoherenceState {
|
class CoherenceState {
|
||||||
public:
|
public:
|
||||||
virtual ~CoherenceState() {}
|
virtual ~CoherenceState() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A virtual base opaque structure used to hold
|
/** This packet's coherence state. Caches should use
|
||||||
coherence status messages. */
|
* dynamic_cast<> to cast to the state appropriate for the
|
||||||
CoherenceState *coherence; // virtual base opaque,
|
* system's coherence protocol. */
|
||||||
// assert(dynamic_cast<Foo>) etc.
|
CoherenceState *coherence;
|
||||||
|
|
||||||
|
/** A virtual base opaque structure used to hold state associated
|
||||||
|
* with the packet but specific to the sending device (e.g., an
|
||||||
|
* MSHR). A pointer to this state is returned in the packet's
|
||||||
|
* response so that the sender can quickly look up the state
|
||||||
|
* needed to process it. A specific subclass would be derived
|
||||||
|
* from this to carry state specific to a particular sending
|
||||||
|
* device. */
|
||||||
class SenderState {
|
class SenderState {
|
||||||
public:
|
public:
|
||||||
virtual ~SenderState() {}
|
virtual ~SenderState() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A virtual base opaque structure used to hold the senders state. */
|
/** This packet's sender state. Devices should use dynamic_cast<>
|
||||||
SenderState *senderState; // virtual base opaque,
|
* to cast to the state appropriate to the sender. */
|
||||||
// assert(dynamic_cast<Foo>) etc.
|
SenderState *senderState;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** List of command attributes. */
|
/** List of command attributes. */
|
||||||
|
@ -144,9 +160,11 @@ class Packet
|
||||||
WriteResp = IsWrite | IsResponse
|
WriteResp = IsWrite | IsResponse
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Return the string name of the cmd field (for debugging and
|
||||||
|
* tracing). */
|
||||||
const std::string &cmdString() const;
|
const std::string &cmdString() const;
|
||||||
|
|
||||||
/** The command of the transaction. */
|
/** The command field of the packet. */
|
||||||
Command cmd;
|
Command cmd;
|
||||||
|
|
||||||
bool isRead() { return (cmd & IsRead) != 0; }
|
bool isRead() { return (cmd & IsRead) != 0; }
|
||||||
|
@ -154,20 +172,7 @@ class Packet
|
||||||
bool isResponse() { return (cmd & IsResponse) != 0; }
|
bool isResponse() { return (cmd & IsResponse) != 0; }
|
||||||
bool needsResponse() { return (cmd & NeedsResponse) != 0; }
|
bool needsResponse() { return (cmd & NeedsResponse) != 0; }
|
||||||
|
|
||||||
void makeTimingResponse() {
|
/** Possible results of a packet's request. */
|
||||||
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
|
enum Result
|
||||||
{
|
{
|
||||||
Success,
|
Success,
|
||||||
|
@ -175,7 +180,7 @@ class Packet
|
||||||
Unknown
|
Unknown
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The result of the packet transaction. */
|
/** The result of this packet's request. */
|
||||||
Result result;
|
Result result;
|
||||||
|
|
||||||
/** Accessor function that returns the source index of the packet. */
|
/** Accessor function that returns the source index of the packet. */
|
||||||
|
@ -193,27 +198,56 @@ class Packet
|
||||||
int getSize() const { assert(sizeValid); return size; }
|
int getSize() const { assert(sizeValid); return size; }
|
||||||
void setSize(int _size) { size = _size; sizeValid = true; }
|
void setSize(int _size) { size = _size; sizeValid = true; }
|
||||||
|
|
||||||
|
/** Constructor. Note that a Request object must be constructed
|
||||||
|
* first, but the Requests's physical address and size fields
|
||||||
|
* need not be valid. The command and destination addresses
|
||||||
|
* must be supplied. */
|
||||||
Packet(Request *_req, Command _cmd, short _dest)
|
Packet(Request *_req, Command _cmd, short _dest)
|
||||||
: data(NULL), staticData(false), dynamicData(false), arrayData(false),
|
: data(NULL), staticData(false), dynamicData(false), arrayData(false),
|
||||||
addr(_req->paddr), size(_req->size), dest(_dest),
|
addr(_req->paddr), size(_req->size), dest(_dest),
|
||||||
addrValid(_req->validPaddr), sizeValid(_req->validSize),
|
addrValid(_req->validPaddr), sizeValid(_req->validSize),
|
||||||
srcValid(false),
|
srcValid(false),
|
||||||
req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
|
req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
|
||||||
time(curTick), result(Unknown)
|
result(Unknown)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Destructor. */
|
||||||
~Packet()
|
~Packet()
|
||||||
{ deleteData(); }
|
{ deleteData(); }
|
||||||
|
|
||||||
|
/** Reinitialize packet address and size from the associated
|
||||||
/** Minimally reset a packet so something like simple cpu can reuse it. */
|
* Request object, and reset other fields that may have been
|
||||||
void reset();
|
* modified by a previous transaction. Typically called when a
|
||||||
|
* statically allocated Request/Packet pair is reused for
|
||||||
|
* multiple transactions. */
|
||||||
void reinitFromRequest() {
|
void reinitFromRequest() {
|
||||||
if (req->validPaddr) setAddr(req->paddr);
|
assert(req->validPaddr);
|
||||||
if (req->validSize) setSize(req->size);
|
setAddr(req->paddr);
|
||||||
|
assert(req->validSize);
|
||||||
|
setSize(req->size);
|
||||||
|
result = Unknown;
|
||||||
|
if (dynamicData) {
|
||||||
|
deleteData();
|
||||||
|
dynamicData = false;
|
||||||
|
arrayData = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Take a request packet and modify it in place to be suitable
|
||||||
|
* for returning as a response to that request. Used for timing
|
||||||
|
* accesses only. For atomic and functional accesses, the
|
||||||
|
* request packet is always implicitly passed back *without*
|
||||||
|
* modifying the command or destination fields, so this function
|
||||||
|
* should not be called. */
|
||||||
|
void makeTimingResponse() {
|
||||||
|
assert(needsResponse());
|
||||||
|
int icmd = (int)cmd;
|
||||||
|
icmd &= ~(IsRequest | NeedsResponse);
|
||||||
|
icmd |= IsResponse;
|
||||||
|
cmd = (Command)icmd;
|
||||||
|
dest = src;
|
||||||
|
srcValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set the data pointer to the following value that should not be freed. */
|
/** Set the data pointer to the following value that should not be freed. */
|
||||||
|
|
|
@ -139,8 +139,7 @@ Tick
|
||||||
PhysicalMemory::doAtomicAccess(Packet *pkt)
|
PhysicalMemory::doAtomicAccess(Packet *pkt)
|
||||||
{
|
{
|
||||||
doFunctionalAccess(pkt);
|
doFunctionalAccess(pkt);
|
||||||
pkt->time = curTick + lat;
|
return lat;
|
||||||
return curTick + lat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -165,9 +165,10 @@ class Port
|
||||||
*/
|
*/
|
||||||
bool sendTiming(Packet *pkt) { return peer->recvTiming(pkt); }
|
bool sendTiming(Packet *pkt) { return peer->recvTiming(pkt); }
|
||||||
|
|
||||||
/** Function called by the associated device to send an atomic access,
|
/** Function called by the associated device to send an atomic
|
||||||
an access in which the data is moved and the state is updated in one
|
* access, an access in which the data is moved and the state is
|
||||||
cycle, without interleaving with other memory accesses.
|
* updated in one cycle, without interleaving with other memory
|
||||||
|
* accesses. Returns estimated latency of access.
|
||||||
*/
|
*/
|
||||||
Tick sendAtomic(Packet *pkt)
|
Tick sendAtomic(Packet *pkt)
|
||||||
{ return peer->recvAtomic(pkt); }
|
{ return peer->recvAtomic(pkt); }
|
||||||
|
|
Loading…
Reference in a new issue