First steps toward getting full system to work with
TimingSimpleCPU. Not there yet. cpu/simple/atomic.cc: Only read SC result if store was an SC. Don't fake SC here; fake it in PhysicalMemory so all CPU models can share in the joy. cpu/simple/timing.cc: Don't forget to checkForInterrupts(). Only fetch subsequent instruction if we're still running (i.e. not quiesced). dev/io_device.hh: Initialize port pointer in SendEvent object. mem/physical.cc: Move fake SC "implementation" here from AtomicSimpleCPU. mem/request.hh: Initialize flags to all clear, not uninitialized. Otherwise we can't reliably look at flags w/o explicitly setting them every time we create a request. --HG-- extra : convert_revision : ae7601ce6fb54c54e19848aa5391327f9a6e61a6
This commit is contained in:
parent
796fa429fe
commit
86777c9db1
5 changed files with 22 additions and 12 deletions
|
@ -349,20 +349,16 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
|
||||||
dcache_access = true;
|
dcache_access = true;
|
||||||
|
|
||||||
assert(data_write_pkt->result == Success);
|
assert(data_write_pkt->result == Success);
|
||||||
}
|
|
||||||
|
|
||||||
if (res && (fault == NoFault))
|
if (res && data_write_req->getFlags() & LOCKED) {
|
||||||
*res = data_write_pkt->result;
|
*res = data_write_req->getScResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This will need a new way to tell if it's hooked up to a cache or not.
|
// This will need a new way to tell if it's hooked up to a cache or not.
|
||||||
if (data_write_req->getFlags() & UNCACHEABLE)
|
if (data_write_req->getFlags() & UNCACHEABLE)
|
||||||
recordEvent("Uncached Write");
|
recordEvent("Uncached Write");
|
||||||
|
|
||||||
// @todo this is a hack and only works on uniprocessor systems
|
|
||||||
// some one else can implement LL/SC.
|
|
||||||
if (data_write_req->getFlags() & LOCKED)
|
|
||||||
*res = 1;
|
|
||||||
|
|
||||||
// If the write needs to have a fault on the access, consider calling
|
// If the write needs to have a fault on the access, consider calling
|
||||||
// changeStatus() and changing it to "bad addr write" or something.
|
// changeStatus() and changing it to "bad addr write" or something.
|
||||||
return fault;
|
return fault;
|
||||||
|
|
|
@ -75,6 +75,9 @@ TimingSimpleCPU::CpuPort::recvFunctional(Packet *pkt)
|
||||||
void
|
void
|
||||||
TimingSimpleCPU::CpuPort::recvStatusChange(Status status)
|
TimingSimpleCPU::CpuPort::recvStatusChange(Status status)
|
||||||
{
|
{
|
||||||
|
if (status == RangeChange)
|
||||||
|
return;
|
||||||
|
|
||||||
panic("TimingSimpleCPU doesn't expect recvStatusChange callback!");
|
panic("TimingSimpleCPU doesn't expect recvStatusChange callback!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,6 +345,8 @@ TimingSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
|
||||||
void
|
void
|
||||||
TimingSimpleCPU::fetch()
|
TimingSimpleCPU::fetch()
|
||||||
{
|
{
|
||||||
|
checkForInterrupts();
|
||||||
|
|
||||||
Request *ifetch_req = new Request(true);
|
Request *ifetch_req = new Request(true);
|
||||||
ifetch_req->setSize(sizeof(MachInst));
|
ifetch_req->setSize(sizeof(MachInst));
|
||||||
|
|
||||||
|
@ -380,7 +385,12 @@ TimingSimpleCPU::completeInst(Fault fault)
|
||||||
|
|
||||||
advancePC(fault);
|
advancePC(fault);
|
||||||
|
|
||||||
fetch();
|
if (_status == Running) {
|
||||||
|
// kick off fetch of next instruction... callback from icache
|
||||||
|
// response will cause that instruction to be executed,
|
||||||
|
// keeping the CPU running.
|
||||||
|
fetch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -397,6 +407,7 @@ TimingSimpleCPU::completeIfetch()
|
||||||
Fault fault = curStaticInst->initiateAcc(this, traceData);
|
Fault fault = curStaticInst->initiateAcc(this, traceData);
|
||||||
assert(fault == NoFault);
|
assert(fault == NoFault);
|
||||||
assert(_status == DcacheWaitResponse);
|
assert(_status == DcacheWaitResponse);
|
||||||
|
// instruction will complete in dcache response callback
|
||||||
} else {
|
} else {
|
||||||
// non-memory instruction: execute completely now
|
// non-memory instruction: execute completely now
|
||||||
Fault fault = curStaticInst->execute(this, traceData);
|
Fault fault = curStaticInst->execute(this, traceData);
|
||||||
|
|
|
@ -90,7 +90,7 @@ class PioPort : public Port
|
||||||
Packet *packet;
|
Packet *packet;
|
||||||
|
|
||||||
SendEvent(PioPort *p, Packet *pkt, Tick t)
|
SendEvent(PioPort *p, Packet *pkt, Tick t)
|
||||||
: Event(&mainEventQueue), packet(pkt)
|
: Event(&mainEventQueue), port(p), packet(pkt)
|
||||||
{ schedule(curTick + t); }
|
{ schedule(curTick + t); }
|
||||||
|
|
||||||
virtual void process();
|
virtual void process();
|
||||||
|
|
|
@ -155,6 +155,11 @@ PhysicalMemory::doFunctionalAccess(Packet *pkt)
|
||||||
case Write:
|
case Write:
|
||||||
memcpy(pmem_addr + pkt->addr - base_addr, pkt->getPtr<uint8_t>(),
|
memcpy(pmem_addr + pkt->addr - base_addr, pkt->getPtr<uint8_t>(),
|
||||||
pkt->size);
|
pkt->size);
|
||||||
|
// temporary hack: will need to add real LL/SC implementation
|
||||||
|
// for cacheless systems later.
|
||||||
|
if (pkt->req->getFlags() & LOCKED) {
|
||||||
|
pkt->req->setScResult(1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("unimplemented");
|
panic("unimplemented");
|
||||||
|
|
|
@ -97,8 +97,6 @@ class Request
|
||||||
|
|
||||||
/** Flag structure for the request. */
|
/** Flag structure for the request. */
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
/** Wether or not flags is valid (has been written yet). */
|
|
||||||
bool validFlags;
|
|
||||||
|
|
||||||
//Accsesors for non-cpu request fields
|
//Accsesors for non-cpu request fields
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in a new issue