Merge "gem5: restore works now"
This commit is contained in:
@ -289,21 +289,21 @@ AtomicSimpleCPU::readMem(Addr addr, uint8_t * data,
|
|||||||
}
|
}
|
||||||
dcache_access = true;
|
dcache_access = true;
|
||||||
|
|
||||||
// FAIL*
|
// FAIL*
|
||||||
#ifdef CONFIG_EVENT_TRAP
|
#ifdef CONFIG_EVENT_TRAP
|
||||||
if(pkt.isError()) {
|
if(pkt.isError()) {
|
||||||
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
|
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
|
||||||
fail::simulator.onTrap(cpu, 0);
|
fail::simulator.onTrap(cpu, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert(!pkt.isError());
|
assert(!pkt.isError());
|
||||||
|
|
||||||
// FAIL*
|
// FAIL*
|
||||||
#ifdef CONFIG_EVENT_MEMREAD
|
#ifdef CONFIG_EVENT_MEMREAD
|
||||||
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
|
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
|
||||||
fail::simulator.onMemoryAccess(cpu, pkt.getAddr(), pkt.getSize(), false, instAddr());
|
fail::simulator.onMemoryAccess(cpu, pkt.getAddr(), pkt.getSize(), false, instAddr());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (req->isLLSC()) {
|
if (req->isLLSC()) {
|
||||||
TheISA::handleLockedRead(thread, req);
|
TheISA::handleLockedRead(thread, req);
|
||||||
@ -405,21 +405,21 @@ AtomicSimpleCPU::writeMem(uint8_t *data, unsigned size,
|
|||||||
}
|
}
|
||||||
dcache_access = true;
|
dcache_access = true;
|
||||||
|
|
||||||
// FAIL*
|
// FAIL*
|
||||||
#ifdef CONFIG_EVENT_TRAP
|
#ifdef CONFIG_EVENT_TRAP
|
||||||
if(pkt.isError()) {
|
if(pkt.isError()) {
|
||||||
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
|
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
|
||||||
fail::simulator.onTrap(cpu, 0);
|
fail::simulator.onTrap(cpu, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert(!pkt.isError());
|
assert(!pkt.isError());
|
||||||
|
|
||||||
// FAIL*
|
// FAIL*
|
||||||
#ifdef CONFIG_EVENT_MEMWRITE
|
#ifdef CONFIG_EVENT_MEMWRITE
|
||||||
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
|
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
|
||||||
fail::simulator.onMemoryAccess(cpu, pkt.getAddr(), pkt.getSize(), true, instAddr());
|
fail::simulator.onMemoryAccess(cpu, pkt.getAddr(), pkt.getSize(), true, instAddr());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (req->isSwap()) {
|
if (req->isSwap()) {
|
||||||
assert(res);
|
assert(res);
|
||||||
@ -486,6 +486,18 @@ AtomicSimpleCPU::tick()
|
|||||||
bool needToFetch = !isRomMicroPC(pcState.microPC()) &&
|
bool needToFetch = !isRomMicroPC(pcState.microPC()) &&
|
||||||
!curMacroStaticInst;
|
!curMacroStaticInst;
|
||||||
if (needToFetch) {
|
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);
|
setupFetchRequest(&ifetch_req);
|
||||||
fault = thread->itb->translateAtomic(&ifetch_req, tc,
|
fault = thread->itb->translateAtomic(&ifetch_req, tc,
|
||||||
BaseTLB::Execute);
|
BaseTLB::Execute);
|
||||||
@ -513,22 +525,22 @@ AtomicSimpleCPU::tick()
|
|||||||
else
|
else
|
||||||
icache_latency = icachePort.sendAtomic(&ifetch_pkt);
|
icache_latency = icachePort.sendAtomic(&ifetch_pkt);
|
||||||
|
|
||||||
// FAIL*
|
// FAIL*
|
||||||
#ifdef CONFIG_EVENT_TRAP
|
#ifdef CONFIG_EVENT_TRAP
|
||||||
if(ifetch_pkt.isError())
|
if(ifetch_pkt.isError())
|
||||||
{
|
{
|
||||||
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
|
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
|
||||||
fail::simulator.onTrap(cpu, 0);
|
fail::simulator.onTrap(cpu, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert(!ifetch_pkt.isError());
|
assert(!ifetch_pkt.isError());
|
||||||
|
|
||||||
// FAIL*
|
// FAIL*
|
||||||
#ifdef CONFIG_EVENT_MEMREAD
|
#ifdef CONFIG_EVENT_MEMREAD
|
||||||
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
|
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
|
||||||
fail::simulator.onMemoryAccess(cpu, ifetch_pkt.getAddr(), ifetch_pkt.getSize(), false, instAddr());
|
fail::simulator.onMemoryAccess(cpu, ifetch_pkt.getAddr(), ifetch_pkt.getSize(), false, instAddr());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 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.
|
||||||
|
|||||||
@ -401,13 +401,6 @@ BaseSimpleCPU::preExecute()
|
|||||||
//fetch beyond the MachInst at the current pc.
|
//fetch beyond the MachInst at the current pc.
|
||||||
instPtr = decoder->decode(pcState);
|
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) {
|
if (instPtr) {
|
||||||
stayAtPC = false;
|
stayAtPC = false;
|
||||||
thread->pcState(pcState);
|
thread->pcState(pcState);
|
||||||
|
|||||||
@ -512,6 +512,13 @@ Serializable::unserializeGlobals(Checkpoint *cp)
|
|||||||
globals.unserialize(cp, globals.name());
|
globals.unserialize(cp, globals.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//DanceOS
|
||||||
|
void
|
||||||
|
Serializable::loadStateAll(Checkpoint *cp)
|
||||||
|
{
|
||||||
|
SimObject::loadStateAll(cp);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
debug_serialize(const string &cpt_dir)
|
debug_serialize(const string &cpt_dir)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -170,6 +170,7 @@ class Serializable
|
|||||||
static int ckptPrevCount;
|
static int ckptPrevCount;
|
||||||
static void serializeAll(const std::string &cpt_dir);
|
static void serializeAll(const std::string &cpt_dir);
|
||||||
static void unserializeGlobals(Checkpoint *cp);
|
static void unserializeGlobals(Checkpoint *cp);
|
||||||
|
static void loadStateAll(Checkpoint *cp); //DanceOS
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@ -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
|
#ifdef DEBUG
|
||||||
//
|
//
|
||||||
|
|||||||
@ -139,6 +139,7 @@ class SimObject : public EventManager, public Serializable
|
|||||||
|
|
||||||
// static: call nameOut() & serialize() on all SimObjects
|
// static: call nameOut() & serialize() on all SimObjects
|
||||||
static void serializeAll(std::ostream &);
|
static void serializeAll(std::ostream &);
|
||||||
|
static void loadStateAll(Checkpoint *cp); //DanceOS
|
||||||
|
|
||||||
// Methods to drain objects in order to take checkpoints
|
// Methods to drain objects in order to take checkpoints
|
||||||
// Or switch from timing -> atomic memory model
|
// Or switch from timing -> atomic memory model
|
||||||
|
|||||||
@ -15,6 +15,9 @@ void Gem5Controller::startup()
|
|||||||
m_System = GetSystemObject();
|
m_System = GetSystemObject();
|
||||||
m_Mem = new Gem5MemoryManager(m_System);
|
m_Mem = new Gem5MemoryManager(m_System);
|
||||||
|
|
||||||
|
restore_request = false;
|
||||||
|
restore_path = "";
|
||||||
|
|
||||||
int numCtxs = GetNumberOfContexts(m_System);
|
int numCtxs = GetNumberOfContexts(m_System);
|
||||||
for (int i = 0; i < numCtxs; i++) {
|
for (int i = 0; i < numCtxs; i++) {
|
||||||
ConcreteCPU* cpu = new ConcreteCPU(GetCPUId(m_System, i), m_System);
|
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
|
clearListeners();
|
||||||
Root* root = Root::root();
|
restore_request = true;
|
||||||
Checkpoint cp(path);
|
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);
|
root->loadState(&cp);
|
||||||
|
|
||||||
|
restore_request = false;
|
||||||
|
m_Flows.toggle(m_CurrFlow);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Gem5Controller::isRestoreRequest()
|
||||||
|
{
|
||||||
|
return restore_request;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement reboot
|
// TODO: Implement reboot
|
||||||
|
|||||||
@ -22,16 +22,21 @@ namespace fail {
|
|||||||
class Gem5Controller : public SimulatorController {
|
class Gem5Controller : public SimulatorController {
|
||||||
private:
|
private:
|
||||||
System* m_System; //!< the gem5 system object
|
System* m_System; //!< the gem5 system object
|
||||||
|
ExperimentFlow* m_CurrFlow; //!< Stores the current flow for save/restore-operations
|
||||||
#if defined(CONFIG_EVENT_BREAKPOINTS) ||\
|
#if defined(CONFIG_EVENT_BREAKPOINTS) ||\
|
||||||
defined(CONFIG_EVENT_BREAKPOINTS_RANGE)
|
defined(CONFIG_EVENT_BREAKPOINTS_RANGE)
|
||||||
std::string m_Mnemonic; //!< mnemonic of the instr. (only with BPs)
|
std::string m_Mnemonic; //!< mnemonic of the instr. (only with BPs)
|
||||||
#endif
|
#endif
|
||||||
|
bool restore_request;
|
||||||
|
std::string restore_path;
|
||||||
public:
|
public:
|
||||||
void startup();
|
void startup();
|
||||||
~Gem5Controller();
|
~Gem5Controller();
|
||||||
|
|
||||||
bool save(const std::string &path);
|
bool save(const std::string &path);
|
||||||
void restore(const std::string &path);
|
void restore(const std::string &path);
|
||||||
|
void onRestore();
|
||||||
|
bool isRestoreRequest();
|
||||||
void reboot();
|
void reboot();
|
||||||
#if defined(CONFIG_EVENT_BREAKPOINTS) ||\
|
#if defined(CONFIG_EVENT_BREAKPOINTS) ||\
|
||||||
defined(CONFIG_EVENT_BREAKPOINTS_RANGE)
|
defined(CONFIG_EVENT_BREAKPOINTS_RANGE)
|
||||||
|
|||||||
Reference in New Issue
Block a user