gem5: TrapListener implemented
The TrapListener works like in Bochs. Instead of a number to a trap the offset is returned for GEM5. See: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html Conflicts: simulators/gem5/src/cpu/simple/atomic.cc Change-Id: Ia8b2083e3c16315d9c577150f14f16995494b2e6
This commit is contained in:
committed by
Horst Schirmeier
parent
fa1690bd1f
commit
5fbf13d07d
@ -49,6 +49,9 @@
|
|||||||
#include "debug/Faults.hh"
|
#include "debug/Faults.hh"
|
||||||
#include "sim/full_system.hh"
|
#include "sim/full_system.hh"
|
||||||
|
|
||||||
|
#include "sal/SALInst.hpp"
|
||||||
|
#include "config/FailConfig.hpp"
|
||||||
|
|
||||||
namespace ArmISA
|
namespace ArmISA
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -95,9 +98,25 @@ ArmFault::getVector(ThreadContext *tc)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ArmFault::invoke(ThreadContext *tc, StaticInstPtr inst)
|
ArmFault::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
|
// DanceOS
|
||||||
|
#ifdef CONFIG_EVENT_TRAP
|
||||||
|
// GEM5 throws a reset trap during initialization.
|
||||||
|
// This happens before the startup function is called.
|
||||||
|
// This leads to problems because the startup function fills the m_CPUs list.
|
||||||
|
// m_CPUs is needed for the TrapListener.
|
||||||
|
// Therefore, we only react on traps after initialization.
|
||||||
|
// e.g. look at gem5/src/arch/arm/faults.cc -> ArmFault::invoke function.
|
||||||
|
if (fail::simulator.isInitialized()) {
|
||||||
|
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(tc->cpuId());
|
||||||
|
// Instead of a number to a trap the offset is returned for GEM5.
|
||||||
|
// see: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
|
||||||
|
fail::simulator.onTrap(cpu, offset());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// ARM ARM B1.6.3
|
// ARM ARM B1.6.3
|
||||||
FaultBase::invoke(tc);
|
FaultBase::invoke(tc);
|
||||||
if (!FullSystem)
|
if (!FullSystem)
|
||||||
|
|||||||
@ -289,17 +289,9 @@ AtomicSimpleCPU::readMem(Addr addr, uint8_t * data,
|
|||||||
}
|
}
|
||||||
dcache_access = true;
|
dcache_access = true;
|
||||||
|
|
||||||
// FAIL*
|
|
||||||
#ifdef CONFIG_EVENT_TRAP
|
|
||||||
if(pkt.isError()) {
|
|
||||||
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
|
|
||||||
fail::simulator.onTrap(cpu, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
assert(!pkt.isError());
|
assert(!pkt.isError());
|
||||||
|
|
||||||
// FAIL*
|
// DanceOS
|
||||||
#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());
|
||||||
@ -405,17 +397,9 @@ AtomicSimpleCPU::writeMem(uint8_t *data, unsigned size,
|
|||||||
}
|
}
|
||||||
dcache_access = true;
|
dcache_access = true;
|
||||||
|
|
||||||
// FAIL*
|
|
||||||
#ifdef CONFIG_EVENT_TRAP
|
|
||||||
if(pkt.isError()) {
|
|
||||||
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(cpuId());
|
|
||||||
fail::simulator.onTrap(cpu, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
assert(!pkt.isError());
|
assert(!pkt.isError());
|
||||||
|
|
||||||
// FAIL*
|
// DanceOS
|
||||||
#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());
|
||||||
@ -525,15 +509,6 @@ AtomicSimpleCPU::tick()
|
|||||||
else
|
else
|
||||||
icache_latency = icachePort.sendAtomic(&ifetch_pkt);
|
icache_latency = icachePort.sendAtomic(&ifetch_pkt);
|
||||||
|
|
||||||
// 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());
|
assert(!ifetch_pkt.isError());
|
||||||
|
|
||||||
// ifetch_req is initialized to read the instruction directly
|
// ifetch_req is initialized to read the instruction directly
|
||||||
|
|||||||
@ -332,10 +332,10 @@ BaseSimpleCPU::checkForInterrupts()
|
|||||||
Fault interrupt = interrupts->getInterrupt(tc);
|
Fault interrupt = interrupts->getInterrupt(tc);
|
||||||
|
|
||||||
if (interrupt != NoFault) {
|
if (interrupt != NoFault) {
|
||||||
// FAIL*
|
// DanceOS
|
||||||
#ifdef CONFIG_EVENT_INTERRUPT
|
#ifdef CONFIG_EVENT_INTERRUPT
|
||||||
fail::simulator.onInterrupt(dynamic_cast<ArmFault*>(interrupt.get())->offset(), false);
|
fail::simulator.onInterrupt(dynamic_cast<ArmFault*>(interrupt.get())->offset(), false);
|
||||||
#endif
|
#endif
|
||||||
fetchOffset = 0;
|
fetchOffset = 0;
|
||||||
interrupts->updateIntrInfo(tc);
|
interrupts->updateIntrInfo(tc);
|
||||||
interrupt->invoke(tc);
|
interrupt->invoke(tc);
|
||||||
|
|||||||
@ -185,13 +185,8 @@ Pl011::write(PacketPtr pkt)
|
|||||||
switch (daddr) {
|
switch (daddr) {
|
||||||
case UART_DR:
|
case UART_DR:
|
||||||
if ((data & 0xFF) == 0x04 && endOnEOT) {
|
if ((data & 0xFF) == 0x04 && endOnEOT) {
|
||||||
// FAIL*
|
|
||||||
#ifdef CONFIG_EVENT_TRAP
|
|
||||||
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(0);
|
|
||||||
fail::simulator.onTrap(cpu, 0);
|
|
||||||
#endif
|
|
||||||
exitSimLoop("UART received EOT", 0);
|
exitSimLoop("UART received EOT", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
term->out(data & 0xFF);
|
term->out(data & 0xFF);
|
||||||
|
|
||||||
|
|||||||
@ -116,14 +116,7 @@ IsaFake::write(PacketPtr pkt)
|
|||||||
data = pkt->get<uint8_t>();
|
data = pkt->get<uint8_t>();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// FAIL*
|
panic("invalid access size!\n");
|
||||||
#ifdef CONFIG_EVENT_TRAP
|
|
||||||
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(0);
|
|
||||||
fail::simulator.onTrap(cpu, 0);
|
|
||||||
#endif
|
|
||||||
panic("invalid access size!\n");
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
warn("Device %s accessed by write to address %#x size=%d data=%#x\n",
|
warn("Device %s accessed by write to address %#x size=%d data=%#x\n",
|
||||||
name(), pkt->getAddr(), pkt->getSize(), data);
|
name(), pkt->getAddr(), pkt->getSize(), data);
|
||||||
|
|||||||
@ -294,11 +294,6 @@ BaseBus::findPort(Addr addr)
|
|||||||
|
|
||||||
// we should use the range for the default port and it did not
|
// we should use the range for the default port and it did not
|
||||||
// match, or the default port is not set
|
// match, or the default port is not set
|
||||||
// FAIL*
|
|
||||||
#ifdef CONFIG_EVENT_TRAP
|
|
||||||
fail::ConcreteCPU* cpu = &fail::simulator.getCPU(0);
|
|
||||||
fail::simulator.onTrap(cpu, 0);
|
|
||||||
#endif
|
|
||||||
fatal("Unable to find destination for addr %#llx on bus %s\n", addr,
|
fatal("Unable to find destination for addr %#llx on bus %s\n", addr,
|
||||||
name());
|
name());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -129,11 +129,11 @@ Root::loadState(Checkpoint *cp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FAIL*
|
// DanceOS
|
||||||
void
|
void
|
||||||
Root::startup()
|
Root::startup()
|
||||||
{
|
{
|
||||||
fail::simulator.startup();
|
fail::simulator.startup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
Reference in New Issue
Block a user