Architecture changes (only gem5 implementation right now):
- The register manager is gone. It's functionality is now encapsulated in the CPU classes. - For the client, there is the ConcreteCPU class that encapsulates the access to the CPU state (including registers) and architecture details. The correspondig objects for the CPUs inside the simulator can be accessed through the SimulatorController.getCPU() function. - Listener got a new ConcreteCPU* member to filter for which CPU the events should fire. The default NULL is used as wildcard for all aviable CPUs. The events respectively got a ConcreteCPU* member to indicate which CPU really fired the event. - For the server, there is CPUArchitecture to access the architecture details. git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1966 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
59
src/core/sal/gem5/Gem5ArmCPU.cc
Normal file
59
src/core/sal/gem5/Gem5ArmCPU.cc
Normal file
@ -0,0 +1,59 @@
|
||||
#include "Gem5ArmCPU.hpp"
|
||||
|
||||
namespace fail {
|
||||
|
||||
regdata_t Gem5ArmCPU::getRegisterContent(Register* reg)
|
||||
{
|
||||
switch (reg->getType()) {
|
||||
case RT_GP:
|
||||
return m_System->getThreadContext(m_Id)->readIntReg(reg->getIndex());
|
||||
|
||||
case RT_FP:
|
||||
return m_System->getThreadContext(m_Id)->readFloatReg(reg->getIndex());
|
||||
|
||||
case RT_ST:
|
||||
return m_System->getThreadContext(m_Id)->readMiscReg(reg->getIndex());
|
||||
|
||||
case RT_IP:
|
||||
return getRegisterContent(getRegister(RI_IP));
|
||||
}
|
||||
|
||||
// This shouldn't be reached if a valid register is passed
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Gem5ArmCPU::setRegisterContent(Register* reg, regdata_t value)
|
||||
{
|
||||
switch (reg->getType()) {
|
||||
case RT_GP:
|
||||
m_System->getThreadContext(m_Id)->setIntReg(reg->getIndex(), value);
|
||||
break;
|
||||
|
||||
case RT_FP:
|
||||
m_System->getThreadContext(m_Id)->setFloatReg(reg->getIndex(), value);
|
||||
break;
|
||||
|
||||
case RT_ST:
|
||||
return m_System->getThreadContext(m_Id)->setMiscReg(reg->getIndex(), value);
|
||||
|
||||
case RT_IP:
|
||||
return setRegisterContent(getRegister(RI_IP), value);
|
||||
}
|
||||
}
|
||||
|
||||
address_t Gem5ArmCPU::getInstructionPointer()
|
||||
{
|
||||
return getRegisterContent(getRegister(RI_IP));
|
||||
}
|
||||
|
||||
address_t Gem5ArmCPU::getStackPointer()
|
||||
{
|
||||
return getRegisterContent(getRegister(RI_SP));
|
||||
}
|
||||
|
||||
address_t Gem5ArmCPU::getLinkRegister()
|
||||
{
|
||||
return getRegisterContent(getRegister(RI_LR));
|
||||
}
|
||||
|
||||
} // end-of-namespace: fail
|
||||
32
src/core/sal/gem5/Gem5ArmCPU.hpp
Normal file
32
src/core/sal/gem5/Gem5ArmCPU.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef __GEM5_ARM_CPU_HPP__
|
||||
#define __GEM5_ARM_CPU_HPP__
|
||||
|
||||
#include "../arm/arch.hpp"
|
||||
|
||||
#include "sim/system.hh"
|
||||
|
||||
namespace fail {
|
||||
|
||||
class Gem5ArmCPU : public ArmArchitecture, public ArmCPUState
|
||||
{
|
||||
public:
|
||||
Gem5ArmCPU(unsigned int id, System* system) : m_Id(id), m_System(system) {}
|
||||
regdata_t getRegisterContent(Register* reg);
|
||||
void setRegisterContent(Register* reg, regdata_t value);
|
||||
|
||||
address_t getInstructionPointer();
|
||||
address_t getStackPointer();
|
||||
address_t getLinkRegister();
|
||||
|
||||
unsigned int getId() { return m_Id; }
|
||||
|
||||
private:
|
||||
unsigned int m_Id;
|
||||
System* m_System;
|
||||
};
|
||||
|
||||
typedef Gem5ArmCPU ConcreteCPU;
|
||||
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif // __GEM5_ARM_CPU_HPP__
|
||||
@ -3,8 +3,25 @@
|
||||
|
||||
#include "../Listener.hpp"
|
||||
|
||||
#include "sim/system.hh"
|
||||
|
||||
namespace fail {
|
||||
|
||||
void Gem5Controller::startup()
|
||||
{
|
||||
// Assuming there is only one defined system should be sufficient for most cases. More systems
|
||||
// are only used for switching cpu model or caches during a simulation run.
|
||||
System* sys = System::systemList.front();
|
||||
m_Mem = new Gem5MemoryManager(sys);
|
||||
|
||||
for (int i = 0; i < sys->numContexts(); i++) {
|
||||
ConcreteCPU* cpu = new ConcreteCPU(sys->getThreadContext(i)->cpuId(), System::systemList.front());
|
||||
addCPU(cpu);
|
||||
}
|
||||
|
||||
SimulatorController::startup();
|
||||
}
|
||||
|
||||
bool Gem5Controller::save(const std::string &path)
|
||||
{
|
||||
connector.save(path);
|
||||
@ -23,27 +40,4 @@ void Gem5Controller::reboot()
|
||||
|
||||
}
|
||||
|
||||
void Gem5Controller::onBreakpoint(address_t instrPtr, address_t address_space)
|
||||
{
|
||||
bool do_fire = false;
|
||||
// Check for active breakpoint-events:
|
||||
ListenerManager::iterator it = m_LstList.begin();
|
||||
BPEvent tmp(instrPtr, address_space);
|
||||
while (it != m_LstList.end()) {
|
||||
BaseListener* pLi = *it;
|
||||
BPListener* pBreakpt = dynamic_cast<BPListener*>(pLi);
|
||||
if (pBreakpt != NULL && pBreakpt->isMatching(&tmp)) {
|
||||
pBreakpt->setTriggerInstructionPointer(instrPtr);
|
||||
it = m_LstList.makeActive(it);
|
||||
do_fire = true;
|
||||
// "it" has already been set to the next element (by calling
|
||||
// makeActive()):
|
||||
continue; // -> skip iterator increment
|
||||
}
|
||||
it++;
|
||||
}
|
||||
if (do_fire)
|
||||
m_LstList.triggerActiveListeners();
|
||||
}
|
||||
|
||||
} // end-of-namespace: fail
|
||||
|
||||
@ -14,14 +14,7 @@ namespace fail {
|
||||
*/
|
||||
class Gem5Controller : public SimulatorController {
|
||||
public:
|
||||
void startup()
|
||||
{
|
||||
SimulatorController::startup();
|
||||
|
||||
m_Mem = new Gem5MemoryManager(System::systemList.front());
|
||||
}
|
||||
|
||||
void onBreakpoint(address_t instrPtr, address_t address_space);
|
||||
void startup();
|
||||
|
||||
bool save(const std::string &path);
|
||||
void restore(const std::string &path);
|
||||
|
||||
@ -15,7 +15,7 @@ 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); }
|
||||
virtual void process(ThreadContext *tc) { fail::simulator.onBreakpoint(&fail::simulator.getCPU(tc->cpuId()), this->evpc, fail::ANY_ADDR); }
|
||||
};
|
||||
|
||||
aspect Gem5Listener
|
||||
|
||||
@ -9,7 +9,7 @@ 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']
|
||||
gStaticLibs = ['-lfail-sal', '-lfail-arch-test', '-lfail-comm', '-lfail-cpn', '-lfail-efw', '-lfail-util', '-lpcl', '-lprotobuf']
|
||||
|
||||
if (len(gStaticLibs)>0):
|
||||
linkFlags = ['-Wl,--start-group']
|
||||
|
||||
Reference in New Issue
Block a user