X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcpu%2Fsimple%2Fatomic.cc;h=be6f421b3289fa04102b979bd5189766e64186c8;hb=971bb55369a53630349aeb5887cb20599d4396ee;hp=3cad6e43f4885ce3ad0ee9840bcee24e25737b1f;hpb=53510f184452c46868a9e6ece9ccb7f30ab70843;p=gem5.git diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 3cad6e43f..be6f421b3 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -24,6 +24,8 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Steve Reinhardt */ #include "arch/utility.hh" @@ -68,11 +70,11 @@ AtomicSimpleCPU::init() BaseCPU::init(); #if FULL_SYSTEM - for (int i = 0; i < execContexts.size(); ++i) { - ExecContext *xc = execContexts[i]; + for (int i = 0; i < threadContexts.size(); ++i) { + ThreadContext *tc = threadContexts[i]; // initialize CPU, including PC - TheISA::initCPU(xc, xc->readCpuId()); + TheISA::initCPU(tc, tc->readCpuId()); } #endif } @@ -106,11 +108,10 @@ AtomicSimpleCPU::CpuPort::recvStatusChange(Status status) panic("AtomicSimpleCPU doesn't expect recvStatusChange callback!"); } -Packet * +void AtomicSimpleCPU::CpuPort::recvRetry() { panic("AtomicSimpleCPU doesn't expect recvRetry callback!"); - return NULL; } @@ -121,26 +122,17 @@ AtomicSimpleCPU::AtomicSimpleCPU(Params *p) { _status = Idle; - ifetch_req = new Request(true); - ifetch_req->setAsid(0); - // @todo fix me and get the real cpu iD!!! - ifetch_req->setCpuNum(0); - ifetch_req->setSize(sizeof(MachInst)); + // @todo fix me and get the real cpu id & thread number!!! + ifetch_req = new Request(); ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast); ifetch_pkt->dataStatic(&inst); - 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_req = new Request(); data_read_pkt = new Packet(data_read_req, Packet::ReadReq, Packet::Broadcast); data_read_pkt->dataStatic(&dataReg); - 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_req = new Request(); data_write_pkt = new Packet(data_write_req, Packet::WriteReq, Packet::Broadcast); } @@ -153,8 +145,8 @@ AtomicSimpleCPU::~AtomicSimpleCPU() void AtomicSimpleCPU::serialize(ostream &os) { - BaseSimpleCPU::serialize(os); SERIALIZE_ENUM(_status); + BaseSimpleCPU::serialize(os); nameOut(os, csprintf("%s.tickEvent", name())); tickEvent.serialize(os); } @@ -162,21 +154,18 @@ AtomicSimpleCPU::serialize(ostream &os) void AtomicSimpleCPU::unserialize(Checkpoint *cp, const string §ion) { - BaseSimpleCPU::unserialize(cp, section); UNSERIALIZE_ENUM(_status); + BaseSimpleCPU::unserialize(cp, section); tickEvent.unserialize(cp, csprintf("%s.tickEvent", section)); } void -AtomicSimpleCPU::switchOut(Sampler *s) +AtomicSimpleCPU::switchOut() { - sampler = s; - if (status() == Running) { - _status = SwitchedOut; + assert(status() == Running || status() == Idle); + _status = SwitchedOut; - tickEvent.squash(); - } - sampler->signalSwitched(); + tickEvent.squash(); } @@ -187,11 +176,11 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU) assert(!tickEvent.scheduled()); - // if any of this CPU's ExecContexts are active, mark the CPU as + // if any of this CPU's ThreadContexts are active, mark the CPU as // running and schedule its tick event. - for (int i = 0; i < execContexts.size(); ++i) { - ExecContext *xc = execContexts[i]; - if (xc->status() == ExecContext::Active && _status != Running) { + for (int i = 0; i < threadContexts.size(); ++i) { + ThreadContext *tc = threadContexts[i]; + if (tc->status() == ThreadContext::Active && _status != Running) { _status = Running; tickEvent.schedule(curTick); break; @@ -204,7 +193,7 @@ void AtomicSimpleCPU::activateContext(int thread_num, int delay) { assert(thread_num == 0); - assert(cpuXC); + assert(thread); assert(_status == Idle); assert(!tickEvent.scheduled()); @@ -219,7 +208,7 @@ void AtomicSimpleCPU::suspendContext(int thread_num) { assert(thread_num == 0); - assert(cpuXC); + assert(thread); assert(_status == Running); @@ -237,24 +226,20 @@ template Fault AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags) { - data_read_req->setVaddr(addr); - data_read_req->setSize(sizeof(T)); - data_read_req->setFlags(flags); - data_read_req->setTime(curTick); + data_read_req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); if (traceData) { traceData->setAddr(addr); } // translate to physical address - Fault fault = cpuXC->translateDataReadReq(data_read_req); + Fault fault = thread->translateDataReadReq(data_read_req); // Now do the access. if (fault == NoFault) { - data_read_pkt->reset(); data_read_pkt->reinitFromRequest(); - dcache_complete = dcachePort.sendAtomic(data_read_pkt); + dcache_latency = dcachePort.sendAtomic(data_read_pkt); dcache_access = true; assert(data_read_pkt->result == Packet::Success); @@ -316,26 +301,22 @@ template Fault AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) { - data_write_req->setVaddr(addr); - data_write_req->setTime(curTick); - data_write_req->setSize(sizeof(T)); - data_write_req->setFlags(flags); + data_write_req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); if (traceData) { traceData->setAddr(addr); } // translate to physical address - Fault fault = cpuXC->translateDataWriteReq(data_write_req); + Fault fault = thread->translateDataWriteReq(data_write_req); // Now do the access. if (fault == NoFault) { - data_write_pkt->reset(); data = htog(data); - data_write_pkt->dataStatic(&data); 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; assert(data_write_pkt->result == Packet::Success); @@ -411,12 +392,12 @@ AtomicSimpleCPU::tick() checkForInterrupts(); - ifetch_req->resetMin(); - ifetch_pkt->reset(); - Fault fault = setupFetchPacket(ifetch_pkt); + Fault fault = setupFetchRequest(ifetch_req); 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 // into the CPU object's inst field. @@ -426,15 +407,14 @@ AtomicSimpleCPU::tick() postExecute(); if (simulate_stalls) { - // This calculation assumes that the icache and dcache - // access latencies are always a multiple of the CPU's - // cycle time. If not, the next tick event may get - // scheduled at a non-integer multiple of the CPU - // cycle time. - Tick icache_stall = icache_complete - curTick - cycles(1); + Tick icache_stall = icache_latency - cycles(1); Tick dcache_stall = - dcache_access ? dcache_complete - curTick - cycles(1) : 0; - latency += icache_stall + dcache_stall; + dcache_access ? dcache_latency - cycles(1) : 0; + Tick stall_cycles = (icache_stall + dcache_stall) / cycles(1); + if (cycles(stall_cycles) < (icache_stall + dcache_stall)) + latency += cycles(stall_cycles+1); + else + latency += cycles(stall_cycles); } }