gem5: restore works now

The function restore(PATH) can now be used to restore a checkpoint.

Change-Id: I25faf9f6335261d2b3ade4185eae93983ece9f97
This commit is contained in:
Richard Hellwig
2013-11-13 17:15:19 +01:00
parent 87264af79a
commit 45e0b41022
8 changed files with 127 additions and 50 deletions

View File

@ -289,21 +289,21 @@ AtomicSimpleCPU::readMem(Addr addr, uint8_t * data,
}
dcache_access = true;
// FAIL*
#ifdef CONFIG_EVENT_TRAP
if(pkt.isError()) {
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
fail::simulator.onTrap(cpu, 0);
}
#endif
// FAIL*
#ifdef CONFIG_EVENT_TRAP
if(pkt.isError()) {
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
fail::simulator.onTrap(cpu, 0);
}
#endif
assert(!pkt.isError());
// FAIL*
#ifdef CONFIG_EVENT_MEMREAD
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
fail::simulator.onMemoryAccess(cpu, pkt.getAddr(), pkt.getSize(), false, instAddr());
#endif
// FAIL*
#ifdef CONFIG_EVENT_MEMREAD
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
fail::simulator.onMemoryAccess(cpu, pkt.getAddr(), pkt.getSize(), false, instAddr());
#endif
if (req->isLLSC()) {
TheISA::handleLockedRead(thread, req);
@ -404,22 +404,22 @@ AtomicSimpleCPU::writeMem(uint8_t *data, unsigned size,
dcache_latency += dcachePort.sendAtomic(&pkt);
}
dcache_access = true;
// FAIL*
#ifdef CONFIG_EVENT_TRAP
if(pkt.isError()) {
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
fail::simulator.onTrap(cpu, 0);
}
#endif
// FAIL*
#ifdef CONFIG_EVENT_TRAP
if(pkt.isError()) {
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
fail::simulator.onTrap(cpu, 0);
}
#endif
assert(!pkt.isError());
// FAIL*
#ifdef CONFIG_EVENT_MEMWRITE
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
fail::simulator.onMemoryAccess(cpu, pkt.getAddr(), pkt.getSize(), true, instAddr());
#endif
// FAIL*
#ifdef CONFIG_EVENT_MEMWRITE
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
fail::simulator.onMemoryAccess(cpu, pkt.getAddr(), pkt.getSize(), true, instAddr());
#endif
if (req->isSwap()) {
assert(res);
@ -486,6 +486,18 @@ AtomicSimpleCPU::tick()
bool needToFetch = !isRomMicroPC(pcState.microPC()) &&
!curMacroStaticInst;
if (needToFetch) {
//DanceOS
#if defined(CONFIG_EVENT_BREAKPOINTS) || defined(CONFIG_EVENT_BREAKPOINTS_RANGE)
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
fail::simulator.setMnemonic("This feature is not implemented for gem5.");
fail::simulator.onBreakpoint(cpu, instAddr(), -1);
#endif
//DanceOS
if(fail::simulator.isRestoreRequest()) {
fail::simulator.onRestore();
}
setupFetchRequest(&ifetch_req);
fault = thread->itb->translateAtomic(&ifetch_req, tc,
BaseTLB::Execute);
@ -513,22 +525,22 @@ AtomicSimpleCPU::tick()
else
icache_latency = icachePort.sendAtomic(&ifetch_pkt);
// FAIL*
#ifdef CONFIG_EVENT_TRAP
// FAIL*
#ifdef CONFIG_EVENT_TRAP
if(ifetch_pkt.isError())
{
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
fail::simulator.onTrap(cpu, 0);
}
#endif
assert(!ifetch_pkt.isError());
{
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
fail::simulator.onTrap(cpu, 0);
}
#endif
// FAIL*
#ifdef CONFIG_EVENT_MEMREAD
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
fail::simulator.onMemoryAccess(cpu, ifetch_pkt.getAddr(), ifetch_pkt.getSize(), false, instAddr());
#endif
assert(!ifetch_pkt.isError());
// FAIL*
#ifdef CONFIG_EVENT_MEMREAD
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
fail::simulator.onMemoryAccess(cpu, ifetch_pkt.getAddr(), ifetch_pkt.getSize(), false, instAddr());
#endif
// ifetch_req is initialized to read the instruction directly
// into the CPU object's inst field.

View File

@ -401,13 +401,6 @@ BaseSimpleCPU::preExecute()
//fetch beyond the MachInst at the current pc.
instPtr = decoder->decode(pcState);
// FAIL*
#if defined(CONFIG_EVENT_BREAKPOINTS) || defined(CONFIG_EVENT_BREAKPOINTS_RANGE)
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
fail::simulator.setMnemonic(instPtr->getName());
fail::simulator.onBreakpoint(cpu, instAddr(), -1);
#endif
if (instPtr) {
stayAtPC = false;
thread->pcState(pcState);

View File

@ -512,6 +512,13 @@ Serializable::unserializeGlobals(Checkpoint *cp)
globals.unserialize(cp, globals.name());
}
//DanceOS
void
Serializable::loadStateAll(Checkpoint *cp)
{
SimObject::loadStateAll(cp);
}
void
debug_serialize(const string &cpt_dir)
{

View File

@ -170,6 +170,7 @@ class Serializable
static int ckptPrevCount;
static void serializeAll(const std::string &cpt_dir);
static void unserializeGlobals(Checkpoint *cp);
static void loadStateAll(Checkpoint *cp); //DanceOS
};
//

View File

@ -130,6 +130,21 @@ SimObject::serializeAll(ostream &os)
}
}
//DanceOS
// static function: loadState all SimObjects.
//
void
SimObject::loadStateAll(Checkpoint *cp)
{
SimObjectList::iterator ri = simObjectList.begin();
SimObjectList::iterator rend = simObjectList.end();
for (; ri != rend; ++ri) {
SimObject *obj = *ri;
obj->loadState(cp);
}
}
#ifdef DEBUG
//

View File

@ -139,6 +139,7 @@ class SimObject : public EventManager, public Serializable
// static: call nameOut() & serialize() on all SimObjects
static void serializeAll(std::ostream &);
static void loadStateAll(Checkpoint *cp); //DanceOS
// Methods to drain objects in order to take checkpoints
// Or switch from timing -> atomic memory model

View File

@ -15,6 +15,9 @@ void Gem5Controller::startup()
m_System = GetSystemObject();
m_Mem = new Gem5MemoryManager(m_System);
restore_request = false;
restore_path = "";
int numCtxs = GetNumberOfContexts(m_System);
for (int i = 0; i < numCtxs; i++) {
ConcreteCPU* cpu = new ConcreteCPU(GetCPUId(m_System, i), m_System);
@ -53,13 +56,53 @@ bool Gem5Controller::save(const std::string &path)
}
}
void Gem5Controller::restore(const std::string &path)
void Gem5Controller::restore(const std::string& path)
{
// FIXME: not working currently
Root* root = Root::root();
Checkpoint cp(path);
clearListeners();
restore_request = true;
restore_path = path;
m_CurrFlow = m_Flows.getCurrent();
m_Flows.resume();
}
void Gem5Controller::onRestore()
{
/* Get the instance of the root-object from gem5
* The root object seems to be the root of a tree
* that contains all the simulation objects, e.g.
* cpu, memory etc.
* gem5/src/sim/root.cc,root.hh
* */
Root* root = Root::root();
/* Checkpoint is a class of gem5 that is used to
* manage the built-in save and restore function
* of gem5.
* gem5/src/sim/serialize.cc,serialize.hh
* */
Checkpoint cp(restore_path);
/* Set some global variables from checkpoint.
* gem5/src/sim/serialize.cc,serialize.hh
* */
Serializable::unserializeGlobals(&cp);
/* loadStateAll(Checkpoint *cp) is a self-implemented
* function that calls loadState() for all simulation
* objects. (without the root object).
* gem5/src/sim/serialize.cc,serialize.hh
* gem5/src/sim/sim_object.cc,sim_object.hh
* */
Serializable::loadStateAll(&cp);
/* Call loadState() on the root-object.
* gem5/src/sim/root.cc,root.hh
* */
root->loadState(&cp);
restore_request = false;
m_Flows.toggle(m_CurrFlow);
}
bool Gem5Controller::isRestoreRequest()
{
return restore_request;
}
// TODO: Implement reboot

View File

@ -22,16 +22,21 @@ namespace fail {
class Gem5Controller : public SimulatorController {
private:
System* m_System; //!< the gem5 system object
ExperimentFlow* m_CurrFlow; //!< Stores the current flow for save/restore-operations
#if defined(CONFIG_EVENT_BREAKPOINTS) ||\
defined(CONFIG_EVENT_BREAKPOINTS_RANGE)
std::string m_Mnemonic; //!< mnemonic of the instr. (only with BPs)
#endif
bool restore_request;
std::string restore_path;
public:
void startup();
~Gem5Controller();
bool save(const std::string &path);
void restore(const std::string &path);
void onRestore();
bool isRestoreRequest();
void reboot();
#if defined(CONFIG_EVENT_BREAKPOINTS) ||\
defined(CONFIG_EVENT_BREAKPOINTS_RANGE)