/*
* Copyright 2014 Google, Inc.
- * Copyright (c) 2012-2013,2015 ARM Limited
+ * Copyright (c) 2012-2013,2015,2017 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
* Authors: Steve Reinhardt
*/
+#include "cpu/simple/atomic.hh"
+
#include "arch/locked_mem.hh"
#include "arch/mmapped_ipr.hh"
#include "arch/utility.hh"
#include "base/bigint.hh"
#include "base/output.hh"
#include "config/the_isa.hh"
-#include "cpu/simple/atomic.hh"
#include "cpu/exetrace.hh"
#include "debug/Drain.hh"
#include "debug/ExecFaulting.hh"
#include "mem/physical.hh"
#include "params/AtomicSimpleCPU.hh"
#include "sim/faults.hh"
-#include "sim/system.hh"
#include "sim/full_system.hh"
+#include "sim/system.hh"
using namespace std;
using namespace TheISA;
-AtomicSimpleCPU::TickEvent::TickEvent(AtomicSimpleCPU *c)
- : Event(CPU_Tick_Pri), cpu(c)
-{
-}
-
-
-void
-AtomicSimpleCPU::TickEvent::process()
-{
- cpu->tick();
-}
-
-const char *
-AtomicSimpleCPU::TickEvent::description() const
-{
- return "AtomicSimpleCPU tick";
-}
-
void
AtomicSimpleCPU::init()
{
}
AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p)
- : BaseSimpleCPU(p), tickEvent(this), width(p->width), locked(false),
+ : BaseSimpleCPU(p),
+ tickEvent([this]{ tick(); }, "AtomicSimpleCPU tick",
+ false, Event::CPU_Tick_Pri),
+ width(p->width), locked(false),
simulate_data_stalls(p->simulate_data_stalls),
simulate_inst_stalls(p->simulate_inst_stalls),
icachePort(name() + ".icache_port", this),
DrainState
AtomicSimpleCPU::drain()
{
+ // Deschedule any power gating event (if any)
+ deschedulePowerGatingEvent();
+
if (switchedOut())
return DrainState::Drained;
threadInfo[tid]->notIdleFraction = 0;
}
}
+
+ // Reschedule any power gating event (if any)
+ schedulePowerGatingEvent();
}
bool
}
Fault
-AtomicSimpleCPU::readMem(Addr addr, uint8_t * data,
- unsigned size, unsigned flags)
+AtomicSimpleCPU::readMem(Addr addr, uint8_t * data, unsigned size,
+ Request::Flags flags)
{
SimpleExecContext& t_info = *threadInfo[curThread];
SimpleThread* thread = t_info.thread;
}
Fault
-AtomicSimpleCPU::initiateMemRead(Addr addr, unsigned size, unsigned flags)
+AtomicSimpleCPU::initiateMemRead(Addr addr, unsigned size,
+ Request::Flags flags)
{
panic("initiateMemRead() is for timing accesses, and should "
"never be called on AtomicSimpleCPU.\n");
}
Fault
-AtomicSimpleCPU::writeMem(uint8_t *data, unsigned size,
- Addr addr, unsigned flags, uint64_t *res)
+AtomicSimpleCPU::writeMem(uint8_t *data, unsigned size, Addr addr,
+ Request::Flags flags, uint64_t *res)
{
SimpleExecContext& t_info = *threadInfo[curThread];
SimpleThread* thread = t_info.thread;
preExecute();
+ Tick stall_ticks = 0;
if (curStaticInst) {
fault = curStaticInst->execute(&t_info, traceData);
traceData = NULL;
}
+ if (dynamic_pointer_cast<SyscallRetryFault>(fault)) {
+ // Retry execution of system calls after a delay.
+ // Prevents immediate re-execution since conditions which
+ // caused the retry are unlikely to change every tick.
+ stall_ticks += clockEdge(syscallRetryLatency) - curTick();
+ }
+
postExecute();
}
curStaticInst->isFirstMicroop()))
instCnt++;
- Tick stall_ticks = 0;
if (simulate_inst_stalls && icache_access)
stall_ticks += icache_latency;