diff --git a/simulators/gem5/src/base/hashmap.hh b/simulators/gem5/src/base/hashmap.hh index dfdf6ef9..51f23426 100644 --- a/simulators/gem5/src/base/hashmap.hh +++ b/simulators/gem5/src/base/hashmap.hh @@ -76,6 +76,11 @@ #endif #endif +// FAIL* +// don't use unordered map with aspect c++ compiler +#undef HAVE_STD_UNORDERED_MAP +#undef HAVE_STD_TR1_UNORDERED_MAP + // set a default value of 0 #ifndef HAVE_STD_UNORDERED_MAP #define HAVE_STD_UNORDERED_MAP 0 diff --git a/simulators/gem5/src/cpu/simple/base.cc b/simulators/gem5/src/cpu/simple/base.cc index bdc4b0f4..aec594a7 100644 --- a/simulators/gem5/src/cpu/simple/base.cc +++ b/simulators/gem5/src/cpu/simple/base.cc @@ -81,6 +81,9 @@ #include "sim/stats.hh" #include "sim/system.hh" +#include "sal/SALInst.hpp" +#include "config/FailConfig.hpp" + using namespace std; using namespace TheISA; @@ -329,6 +332,10 @@ BaseSimpleCPU::checkForInterrupts() Fault interrupt = interrupts->getInterrupt(tc); if (interrupt != NoFault) { + // FAIL* + #ifdef CONFIG_EVENT_INTERRUPT + fail::simulator.onInterrupt(dynamic_cast(interrupt.get())->offset(), false); + #endif fetchOffset = 0; interrupts->updateIntrInfo(tc); interrupt->invoke(tc); diff --git a/simulators/gem5/src/mem/abstract_mem.cc b/simulators/gem5/src/mem/abstract_mem.cc index c84d6a50..793fb001 100644 --- a/simulators/gem5/src/mem/abstract_mem.cc +++ b/simulators/gem5/src/mem/abstract_mem.cc @@ -62,6 +62,9 @@ #include "mem/packet_access.hh" #include "sim/system.hh" +#include "config/FailConfig.hpp" +#include "sal/SALInst.hpp" + using namespace std; AbstractMemory::AbstractMemory(const Params *p) : @@ -400,6 +403,10 @@ AbstractMemory::access(PacketPtr pkt) bytesRead[pkt->req->masterId()] += pkt->getSize(); if (pkt->req->isInstFetch()) bytesInstRead[pkt->req->masterId()] += pkt->getSize(); + // FAIL* + #ifdef CONFIG_EVENT_MEMREAD + fail::simulator.onMemoryAccess(pkt->getAddr(), pkt->getSize(), false, 0); + #endif } else if (pkt->isWrite()) { if (writeOK(pkt)) { if (pmemAddr) @@ -408,6 +415,10 @@ AbstractMemory::access(PacketPtr pkt) TRACE_PACKET("Write"); numWrites[pkt->req->masterId()]++; bytesWritten[pkt->req->masterId()] += pkt->getSize(); + // FAIL* + #ifdef CONFIG_EVENT_MEMWRITE + fail::simulator.onMemoryAccess(pkt->getAddr(), pkt->getSize(), true, 0); + #endif } } else if (pkt->isInvalidate()) { // no need to do anything @@ -432,11 +443,19 @@ AbstractMemory::functionalAccess(PacketPtr pkt) if (pmemAddr) memcpy(pkt->getPtr(), hostAddr, pkt->getSize()); TRACE_PACKET("Read"); + // FAIL* + #ifdef CONFIG_EVENT_MEMREAD + fail::simulator.onMemoryAccess(pkt->getAddr(), pkt->getSize(), false, 0); + #endif pkt->makeResponse(); } else if (pkt->isWrite()) { if (pmemAddr) memcpy(hostAddr, pkt->getPtr(), pkt->getSize()); TRACE_PACKET("Write"); + // FAIL* + #ifdef CONFIG_EVENT_MEMWRITE + fail::simulator.onMemoryAccess(pkt->getAddr(), pkt->getSize(), true, 0); + #endif pkt->makeResponse(); } else if (pkt->isPrint()) { Packet::PrintReqState *prs = diff --git a/simulators/gem5/src/sim/root.cc b/simulators/gem5/src/sim/root.cc index 34150083..9ac9c57f 100644 --- a/simulators/gem5/src/sim/root.cc +++ b/simulators/gem5/src/sim/root.cc @@ -37,6 +37,8 @@ #include "sim/full_system.hh" #include "sim/root.hh" +#include "sal/SALInst.hpp" + Root *Root::_root = NULL; /* @@ -126,6 +128,14 @@ Root::loadState(Checkpoint *cp) timeSyncEnable(params()->time_sync_enable); } + +// FAIL* +void +Root::startup() +{ + fail::simulator.startup(); +} + void Root::serialize(std::ostream &os) { diff --git a/simulators/gem5/src/sim/root.hh b/simulators/gem5/src/sim/root.hh index 6a7b5dc9..10ca4d6e 100644 --- a/simulators/gem5/src/sim/root.hh +++ b/simulators/gem5/src/sim/root.hh @@ -112,6 +112,9 @@ class Root : public SimObject */ void initState(); + // FAIL* + void startup(); + virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); diff --git a/src/core/sal/CMakeLists.txt b/src/core/sal/CMakeLists.txt index 9c1deb33..58bbdd9f 100644 --- a/src/core/sal/CMakeLists.txt +++ b/src/core/sal/CMakeLists.txt @@ -18,7 +18,6 @@ elseif(BUILD_GEM5) SimulatorController.cc perf/BreakpointBuffer.cc gem5/Gem5Controller.cc - gem5/Gem5PCEvents.cc ) elseif(BUILD_OVP) set(SRCS diff --git a/src/core/sal/gem5/FailGem5Device.cc b/src/core/sal/gem5/FailGem5Device.cc deleted file mode 100644 index eac25f7f..00000000 --- a/src/core/sal/gem5/FailGem5Device.cc +++ /dev/null @@ -1,127 +0,0 @@ -#include "FailGem5Device.hpp" - -#include "debug/Fail.hh" -#include "sim/system.hh" -#include "arch/arm/decoder.hh" -#include "cpu/simple/base.hh" - -#include "../SALInst.hpp" -#include "Gem5PCEvents.hpp" - -#include - -FailGem5Device::FailGem5Device(Params *p) - : BasicPioDevice(p) -{ - pioSize = 0x60; -} - -void FailGem5Device::startup() -{ - // TODO: Find a better way/position to start single stepping. - // It's not possible to fetch the instruction at Adress 0x0 - m_BreakpointNotTaken = new Gem5InstructionEvent(this, &sys->pcEventQueue, 0x80000000); - fail::simulator.startup(); -} - -void FailGem5Device::activateSingleStepMode() -{ - setNextBreakpoints(sys->getThreadContext(0)); -} - -void FailGem5Device::deactivateSingleStepMode() -{ - clearBreakpoints(); -} - -void FailGem5Device::setNextBreakpoints(ThreadContext *tc) -{ - clearBreakpoints(); - - // Get the instruction at the current program counter - MachInst inst; - PCState pc = tc->pcState(); - tc->getVirtProxy().readBlob(pc.pc(), (uint8_t*)&inst, sizeof(MachInst)); - - // Decode the instruction - ArmISA::Decoder* decoder = tc->getDecoderPtr(); - BaseSimpleCPU* cpu = dynamic_cast(tc->getCpuPtr()); - Addr fetchPC = (pc.pc() & cpu->PCMask) + cpu->fetchOffset; - decoder->moreBytes(pc, fetchPC, inst); - StaticInstPtr si = decoder->decode(pc); - - // Set breakpoints - // First breakpoint is always the next pc - // FIXME: Doesn't work properly in Thumb or Thumb2 mode - m_BreakpointNotTaken = new Gem5InstructionEvent(this, &sys->pcEventQueue, pc.npc()); - - // Second breakpoint will only be set if there is a possible change in control flow - DPRINTF(Fail, "Instruction Name: %s\n", si->getName()); - - if(si->getName().compare("bx") == 0) - { - DPRINTF(Fail, "BX instruction\n"); - Addr target = tc->readIntReg(si->machInst.rm); - m_BreakpointTaken = new Gem5InstructionEvent(this, &sys->pcEventQueue, target); - - return; - } - - // Check for a pop instruction with the pc as target - if(si->getName().compare("ldmstm") == 0) - { - std::bitset<16> regs(si->machInst.regList); - if(regs.test(15)) // Bit 15 = pc - { - DPRINTF(Fail, "LDMSTM with pc as target\n"); - Addr mem = tc->readIntReg(si->machInst.rn) + 4*(regs.count()-1); - - Addr target; - tc->getVirtProxy().readBlob(mem, (uint8_t*)&target, sizeof(Addr)); - DPRINTF(Fail, "Value loaded into pc: %x\n", target); - - m_BreakpointTaken = new Gem5InstructionEvent(this, &sys->pcEventQueue, target); - } - return; - } - - PCState bpc; - if(si->hasBranchTarget(pc, tc, bpc)) - { - DPRINTF(Fail, "Immediate branch\n"); - if (bpc.pc() != pc.npc()) - { - m_BreakpointTaken = new Gem5InstructionEvent(this, &sys->pcEventQueue, bpc.pc()); - } - } -} - -void FailGem5Device::clearBreakpoints() -{ - if(m_BreakpointTaken) - { - delete m_BreakpointTaken; - m_BreakpointTaken = 0; - } - if(m_BreakpointNotTaken) - { - delete m_BreakpointNotTaken; - m_BreakpointNotTaken = 0; - } -} - - -Tick FailGem5Device::read(PacketPtr pkt) -{ - return pioDelay; -} - -Tick FailGem5Device::write(PacketPtr pkt) -{ - return pioDelay; -} - -FailGem5Device* FailGem5DeviceParams::create() -{ - return new FailGem5Device(this); -} diff --git a/src/core/sal/gem5/FailGem5Device.hpp b/src/core/sal/gem5/FailGem5Device.hpp deleted file mode 100644 index d097d8af..00000000 --- a/src/core/sal/gem5/FailGem5Device.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __FAILGEM5_DEVICE_HH__ -#define __FAILGEM5_DEVICE_HH__ - -#include "dev/io_device.hh" -#include "params/FailGem5Device.hh" -#include "cpu/thread_context.hh" - -class Gem5InstructionEvent; - -class FailGem5Device : public BasicPioDevice -{ - -public: - typedef FailGem5DeviceParams Params; - FailGem5Device(Params *p); - - void setNextBreakpoints(ThreadContext *tc); - - virtual void startup(); - virtual Tick read(PacketPtr pkt); - virtual Tick write(PacketPtr pkt); - -private: - Gem5InstructionEvent* m_BreakpointTaken; - Gem5InstructionEvent* m_BreakpointNotTaken; - - void activateSingleStepMode(); - void deactivateSingleStepMode(); - void clearBreakpoints(); -}; - -#endif // __FAILGEM5_DEVICE_HH__ diff --git a/src/core/sal/gem5/FailGem5Device.py b/src/core/sal/gem5/FailGem5Device.py deleted file mode 100644 index 41545b92..00000000 --- a/src/core/sal/gem5/FailGem5Device.py +++ /dev/null @@ -1,5 +0,0 @@ -from Device import BasicPioDevice - -class FailGem5Device(BasicPioDevice): - type = 'FailGem5Device' - diff --git a/src/core/sal/gem5/Gem5Config.hpp b/src/core/sal/gem5/Gem5Config.hpp index 3ff56f2a..373a5f62 100644 --- a/src/core/sal/gem5/Gem5Config.hpp +++ b/src/core/sal/gem5/Gem5Config.hpp @@ -7,7 +7,6 @@ #define __GEM5_CONFIG_HPP__ #include "base/types.hh" -//#include "arch/arm/registers.hh" namespace fail { diff --git a/src/core/sal/gem5/Gem5Connector.cc b/src/core/sal/gem5/Gem5Connector.cc new file mode 100644 index 00000000..642a594d --- /dev/null +++ b/src/core/sal/gem5/Gem5Connector.cc @@ -0,0 +1,25 @@ +#include "Gem5Connector.hpp" + +#include "base/trace.hh" +#include "debug/FailState.hh" +#include "sim/root.hh" + +Gem5Connector connector; + +void Gem5Connector::save(const std::string &path) +{ + DPRINTF(FailState, "Saving state to %s.\n", path); + + Root* root = Root::root(); + root->Serializable::serializeAll(path); +} + +void Gem5Connector::restore(const std::string &path) +{ + DPRINTF(FailState, "Restoring state from %s.\n", path); + + Root* root = Root::root(); + Checkpoint cp(path); + + root->loadState(&cp); +} diff --git a/src/core/sal/gem5/Gem5Connector.hpp b/src/core/sal/gem5/Gem5Connector.hpp new file mode 100644 index 00000000..9b012864 --- /dev/null +++ b/src/core/sal/gem5/Gem5Connector.hpp @@ -0,0 +1,20 @@ +#ifndef __GEM5_CONNECTOR_HPP__ + #define __GEM5_CONNECTOR_HPP__ + +#include + +/** + * \class Gem5Connector + * This class will be compiled inside the gem5 context and provides the + * Gem5Controller a way to call gem5 functions. + */ +class Gem5Connector +{ +public: + void save(const std::string &path); + void restore(const std::string &path); +}; + +extern Gem5Connector connector; + +#endif // __GEM5_CONNECTOR_HPP__ diff --git a/src/core/sal/gem5/Gem5Controller.cc b/src/core/sal/gem5/Gem5Controller.cc index e8d9f4f5..6b49d7f2 100644 --- a/src/core/sal/gem5/Gem5Controller.cc +++ b/src/core/sal/gem5/Gem5Controller.cc @@ -1,35 +1,23 @@ #include "Gem5Controller.hpp" - -#include +#include "Gem5Connector.hpp" #include "../Listener.hpp" -#include "sim/core.hh" -#include "sim/sim_exit.hh" -//#include "sim/root.hh" - namespace fail { bool Gem5Controller::save(const std::string &path) { - // Takes a snapshot in the m5out dir - Tick when = curTick() + 1; - exitSimLoop("checkpoint", 0, when, 0); - - // This could be a version to take snapshots with a specified name - /*Root* root = Root::root(); + connector.save(path); - std::ofstream file(path.c_str()); - root->serialize(file); - file.close();*/ - return false; // TODO + return true; } void Gem5Controller::restore(const std::string &path) { - + connector.restore(path); } +// TODO: Implement reboot void Gem5Controller::reboot() { diff --git a/src/core/sal/gem5/Gem5Controller.hpp b/src/core/sal/gem5/Gem5Controller.hpp index f4cb6a58..a38b29a8 100644 --- a/src/core/sal/gem5/Gem5Controller.hpp +++ b/src/core/sal/gem5/Gem5Controller.hpp @@ -1,12 +1,14 @@ #ifndef __GEM5_CONTROLLER_HPP__ #define __GEM5_CONTROLLER_HPP__ -#include - #include "../SimulatorController.hpp" namespace fail { +/** + * \class Gem5Controller + * gem5-specific implementation of a SimulatorController. + */ class Gem5Controller : public SimulatorController { public: void onBreakpoint(address_t instrPtr, address_t address_space); @@ -18,4 +20,4 @@ public: } // end-of-namespace: fail -#endif // __GEM_CONTROLLER_HPP__ +#endif // __GEM5_CONTROLLER_HPP__ diff --git a/src/core/sal/gem5/Gem5Listener.ah b/src/core/sal/gem5/Gem5Listener.ah index be3e556e..a538a411 100644 --- a/src/core/sal/gem5/Gem5Listener.ah +++ b/src/core/sal/gem5/Gem5Listener.ah @@ -1,25 +1,30 @@ -#ifndef __GEM5LISTENER_AH__ - #define __GEM5LISTENER_AH__ +#ifndef __GEM5_LISTENER_AH__ + #define __GEM5_LISTENER_AH__ -#include "config/VariantConfig.hpp" -#include "config/FailConfig.hpp" +#include "../SALInst.hpp" -#if defined(BUILD_GEM5) && defined(CONFIG_EVENT_BREAKPOINTS) - -#include "Gem5PCEvents.hpp" #include "sim/system.hh" +#include "cpu/pc_event.hh" + +class Gem5Breakpoint : public PCEvent +{ +public: + Gem5Breakpoint(PCEventQueue* queue, Addr ip) + : PCEvent(queue, "Fail* experiment breakpoint", ip) {} + virtual void process(ThreadContext *tc) { fail::simulator.onBreakpoint(this->evpc, fail::ANY_ADDR); } +}; aspect Gem5Listener { advice "fail::BPSingleListener" : slice class { private: - Gem5BreakpointEvent* m_Breakpoint; + Gem5Breakpoint* m_Breakpoint; public: virtual bool onAddition() { System* sys = *System::systemList.begin(); - m_Breakpoint = new Gem5BreakpointEvent(&sys->pcEventQueue, this->m_WatchInstrPtr); + m_Breakpoint = new Gem5Breakpoint(&sys->pcEventQueue, this->m_WatchInstrPtr); return true; } @@ -35,5 +40,5 @@ aspect Gem5Listener }; }; -#endif // BUILD_GEM5 && CONFIG_EVENT_BREAKPOINTS -#endif // __GEM5LISTENER_AH__ +#endif // __GEM5_LISTENER_AH__ + diff --git a/src/core/sal/gem5/Gem5PCEvents.cc b/src/core/sal/gem5/Gem5PCEvents.cc deleted file mode 100644 index 817d8f18..00000000 --- a/src/core/sal/gem5/Gem5PCEvents.cc +++ /dev/null @@ -1,14 +0,0 @@ -#include "Gem5PCEvents.hpp" -#include "../SALInst.hpp" - -#include "cpu/thread_context.hh" - -void Gem5BreakpointEvent::process(ThreadContext *tc) -{ - fail::simulator.onBreakpoint(this->evpc, fail::ANY_ADDR); -} - -void Gem5InstructionEvent::process(ThreadContext *tc) -{ - m_FailDevice->setNextBreakpoints(tc); -} diff --git a/src/core/sal/gem5/Gem5PCEvents.hpp b/src/core/sal/gem5/Gem5PCEvents.hpp deleted file mode 100644 index 4230b432..00000000 --- a/src/core/sal/gem5/Gem5PCEvents.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __GEM5_PCEVENTS_HPP__ - #define __GEM5_PCEVENTS_HPP__ - -#include "cpu/pc_event.hh" - -#include "FailGem5Device.hpp" - -class Gem5BreakpointEvent : public PCEvent -{ -public: - Gem5BreakpointEvent(PCEventQueue* queue, Addr ip) - : PCEvent(queue, "Fail breakpoint event", ip) {} - virtual void process(ThreadContext *tc); -}; - -class Gem5InstructionEvent : public PCEvent -{ -public: - Gem5InstructionEvent(FailGem5Device* device, PCEventQueue* queue, Addr ip) - : PCEvent(queue, "Fail instruction event", ip), m_FailDevice(device) {} - virtual void process(ThreadContext *tc); - -private: - FailGem5Device* m_FailDevice; -}; - -#endif // __GEM5_PCEVENTS_HPP__ diff --git a/src/core/sal/gem5/SConscript b/src/core/sal/gem5/SConscript index 362ac8d2..4042e9fa 100644 --- a/src/core/sal/gem5/SConscript +++ b/src/core/sal/gem5/SConscript @@ -6,6 +6,8 @@ if env['TARGET_ISA'] == 'no': env.Prepend(CPPPATH=Dir('../../../../../src/core/')) env.Prepend(CPPPATH=Dir('../../../../../build/src/core/')) +env.Append(CXXFLAGS = '-Wno-deprecated') + env.Prepend(LIBPATH=Dir('../../../../../build/lib/')) gStaticLibs = ['-lfail-sal', '-lfail-hsc-simple', '-lfail-comm', '-lfail-cpn', '-lfail-efw', '-lfail-util', '-lpcl'] @@ -20,6 +22,7 @@ if (len(gStaticLibs)>0): env.Append(LINKCOM = ' $GEN_LIB_BUILD_STATIC') -SimObject('FailGem5Device.py') -Source('FailGem5Device.cc') -DebugFlag('Fail') +DebugFlag('FailState') +CompoundFlag('Fail', ['FailState']) + +Source('Gem5Connector.cc')