Files
fail/src/core/sal/gem5/Gem5Wrapper.cc
Adrian Böckenkamp 08febe5819 gem5 build system improved
Encapsulated gem5-specific code into wrapper functions to separate the
build process (Fail: CMake, gem5: scons). Added some gem5-related FIXMEs.

Another CMake related FIXME added. +some cosmetics.

Change-Id: Id84b480127b1f13aed6a0ee97f3583f410d531c5
2013-04-08 17:57:06 +02:00

102 lines
2.8 KiB
C++

#include "../SALInst.hpp"
#include "Gem5Wrapper.hpp"
#include "Gem5Breakpoint.hpp"
#include "sim/system.hh"
#include "mem/packet.hh"
#include "mem/physical.hh"
namespace fail {
// Register-/Memory-related:
regdata_t GetRegisterContent(System* sys, unsigned int id, RegisterType type, size_t idx)
{
switch (type) {
case RT_GP:
if (idx == 15) {
return sys->getThreadContext(id)->pcState().pc();
}
return sys->getThreadContext(id)->readIntReg(idx);
case RT_FP: return sys->getThreadContext(id)->readFloatReg(idx); // FIXME: correct?! (FP <-> Float?!)
case RT_ST: return sys->getThreadContext(id)->readMiscReg(idx);
case RT_IP: return sys->getThreadContext(id)->pcState().pc();
}
// This shouldn't be reached if a valid register is passed
assert(false && "FATAL ERROR: invalid register type (should never be reached)!");
return 0;
}
void SetRegisterContent(System* sys, unsigned int id, RegisterType type, size_t idx,
regdata_t value)
{
switch (type) {
case RT_GP: sys->getThreadContext(id)->setIntReg(idx, value); break;
case RT_FP: sys->getThreadContext(id)->setFloatReg(idx, value); break; // FIXME: correct?! (FP <-> Float?!)
case RT_ST: sys->getThreadContext(id)->setMiscReg(idx, value); break;
case RT_IP: sys->getThreadContext(id)->pcState().pc(static_cast<Addr>(value)); break;
}
// This shouldn't be reached if a valid register is passed
assert(false && "FATAL ERROR: invalid register type (should never be reached)!");
}
void ReadMemory(System* sys, guest_address_t addr, size_t cnt, void *dest)
{
Request req(addr, cnt, Request::PHYSICAL, 0);
Packet pkt(&req, MemCmd::ReadReq);
pkt.dataStatic(dest);
sys->getPhysMem().functionalAccess(&pkt);
}
void WriteMemory(System* sys, guest_address_t addr, size_t cnt, void const *src)
{
Request req(addr, cnt, Request::PHYSICAL, 0);
Packet pkt(&req, MemCmd::WriteReq);
pkt.dataStatic(src);
sys->getPhysMem().functionalAccess(&pkt);
}
size_t GetPoolSize(System* sys) { return sys->getPhysMem().totalSize(); }
// Breakpoint-related:
void Gem5Breakpoint::process(ThreadContext *tc)
{
fail::simulator.onBreakpoint(&fail::simulator.getCPU(tc->cpuId()), this->evpc, fail::ANY_ADDR);
}
Gem5Breakpoint* OnBreakpointAddition(address_t watchInstrPtr)
{
System* sys = *System::systemList.begin();
// FIXME: begin() vs. front() (see Gem5Controller::startup())
// FIXME: Provide "sys" using the simulator-inst?
return new Gem5Breakpoint(&sys->pcEventQueue, watchInstrPtr);
}
void OnBreakpointDeletion(Gem5Breakpoint* bp)
{
if (bp) {
delete bp; // TODO: required?
}
}
// Controller-related:
unsigned int GetCPUId(System* sys, int context)
{
return sys->getThreadContext(context)->cpuId();
}
System* GetSystemObject()
{
return System::systemList.front();
}
int GetNumberOfContexts(System* sys)
{
return sys->numContexts();
}
} // end-of-namespace: fail