gem5: campaigns are now running without interruption

This change introduces a fake iobus device into gem5 to prevent
it from crashing on bogus I/O memory accesses.

Change-Id: Ie69e3191bdd917cc681269852937a5a3820a93fb
This commit is contained in:
Richard Hellwig
2014-03-17 11:33:55 +01:00
committed by Michael Lenz
parent ea34860bd8
commit b60e1c0c66
8 changed files with 162 additions and 3 deletions

View File

@ -154,6 +154,8 @@ else:
ranges = [test_sys.physmem.range])
test_sys.iobridge.slave = test_sys.iobus.master
test_sys.iobridge.master = test_sys.membus.slave
test_sys.failfake = FailFakeDevice(pio_addr=0xF00); #DanceOS
test_sys.iobus.default = test_sys.failfake.pio #DanceOS
# Sanity check
if options.fastmem and (options.caches or options.l2cache):

View File

@ -130,6 +130,8 @@ else:
ranges = [test_sys.physmem.range])
test_sys.iobridge.slave = test_sys.iobus.master
test_sys.iobridge.master = test_sys.membus.slave
test_sys.failfake = FailFakeDevice(pio_addr=0xF00); #DanceOS
test_sys.iobus.default = test_sys.failfake.pio #DanceOS
# Sanity check
if options.fastmem and (options.caches or options.l2cache):

View File

@ -49,6 +49,7 @@
#include "cpu/exetrace.hh"
#include "debug/ExecFaulting.hh"
#include "debug/SimpleCPU.hh"
#include "debug/Fail.hh" //DanceOS
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "mem/physical.hh"
@ -289,7 +290,11 @@ AtomicSimpleCPU::readMem(Addr addr, uint8_t * data,
}
dcache_access = true;
assert(!pkt.isError());
//DanceOS
//assert(!pkt.isError());
if(pkt.isError()) {
DPRINTF(Fail, "[FAIL] cpu/simple/atomic.cc readMem(): assert(!pkt.isError()) bypassed\n");
}
// DanceOS
#ifdef CONFIG_EVENT_MEMREAD
@ -397,7 +402,11 @@ AtomicSimpleCPU::writeMem(uint8_t *data, unsigned size,
}
dcache_access = true;
assert(!pkt.isError());
//DanceOS
//assert(!pkt.isError());
if(pkt.isError()) {
DPRINTF(Fail, "[FAIL] cpu/simple/atomic.cc writeMem(): assert(!pkt.isError()) bypassed\n");
}
// DanceOS
#ifdef CONFIG_EVENT_MEMWRITE

View File

@ -65,6 +65,19 @@ class IsaFake(BasicPioDevice):
warn_access = Param.String("", "String to print when device is accessed")
fake_mem = Param.Bool(False,
"Is this device acting like a memory and thus may get a cache line sized req")
#DanceOS
class FailFakeDevice(BasicPioDevice):
type = 'FailFakeDevice'
pio_size = Param.Addr(0x8, "Size of address range")
ret_data8 = Param.UInt8(0xFF, "Default data to return")
ret_data16 = Param.UInt16(0xFFFF, "Default data to return")
ret_data32 = Param.UInt32(0xFFFFFFFF, "Default data to return")
ret_data64 = Param.UInt64(0xFFFFFFFFFFFFFFFF, "Default data to return")
ret_bad_addr = Param.Bool(False, "Return pkt status bad address on access")
update_data = Param.Bool(False, "Update the data that is returned on writes")
warn_access = Param.String("", "String to print when device is accessed")
fake_mem = Param.Bool(False,
"Is this device acting like a memory and thus may get a cache line sized req")
class BadAddr(IsaFake):
pio_addr = 0

View File

@ -63,6 +63,7 @@ Source('ide_disk.cc')
Source('intel_8254_timer.cc')
Source('io_device.cc')
Source('isa_fake.cc')
Source('fail_fake_device.cc') #DanceOS
Source('mc146818.cc')
Source('ns_gige.cc')
Source('pciconfigall.cc')

View File

@ -43,6 +43,7 @@
#include "base/trace.hh"
#include "debug/Checkpoint.hh"
#include "debug/Uart.hh"
#include "debug/Fail.hh" //DanceOS
#include "dev/arm/amba_device.hh"
#include "dev/arm/gic.hh"
#include "dev/arm/pl011.hh"
@ -185,7 +186,9 @@ Pl011::write(PacketPtr pkt)
switch (daddr) {
case UART_DR:
if ((data & 0xFF) == 0x04 && endOnEOT) {
exitSimLoop("UART received EOT", 0);
//DanceOS
//exitSimLoop("UART received EOT", 0);
DPRINTF(Fail, "[FAIL] dev/arm/pl011.cc write(): exitSimLoop(\"UART received EOT\", 0) bypassed\n");
}
term->out(data & 0xFF);

View File

@ -0,0 +1,70 @@
#include "base/trace.hh"
#include "debug/Fail.hh"
#include "dev/fail_fake_device.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "sim/system.hh"
#include "config/FailConfig.hpp"
#include "sal/SALInst.hpp"
using namespace std;
FailFakeDevice::FailFakeDevice(Params *p)
: BasicPioDevice(p)
{
if (!p->ret_bad_addr)
pioSize = p->pio_size;
retData8 = p->ret_data8;
retData16 = p->ret_data16;
retData32 = p->ret_data32;
retData64 = p->ret_data64;
}
Tick
FailFakeDevice::read(PacketPtr pkt)
{
pkt->allocate();
pkt->makeAtomicResponse();
DPRINTF(Fail, "[FAIL] dev/fail_fake_device.cc read(): fake response\n");
switch (pkt->getSize()) {
case sizeof(uint64_t):
pkt->set(retData64);
break;
case sizeof(uint32_t):
pkt->set(retData32);
break;
case sizeof(uint16_t):
pkt->set(retData16);
break;
case sizeof(uint8_t):
pkt->set(retData8);
break;
default:
if (params()->fake_mem)
std::memset(pkt->getPtr<uint8_t>(), 0, pkt->getSize());
else
panic("invalid access size! Device being accessed by cache?\n");
}
return pioDelay;
}
Tick
FailFakeDevice::write(PacketPtr pkt)
{
pkt->makeAtomicResponse();
DPRINTF(Fail, "[FAIL] dev/fail_fake_device.cc write(): fake response\n");
return pioDelay;
}
FailFakeDevice *
FailFakeDeviceParams::create()
{
return new FailFakeDevice(this);
}

View File

@ -0,0 +1,59 @@
/** @file
* Declaration of a fake device.
*/
#ifndef __FAIL_FAKE__DEVICE_HH__
#define __FAIL_FAKE__DEVICE_HH__
#include <string>
#include "base/range.hh"
#include "dev/io_device.hh"
#include "mem/packet.hh"
#include "params/FailFakeDevice.hh"
/**
* This device implements a fake device for an iobus.
* On a read this device returns on every request the maximum value.
* On a write nothing happens.
* This device is needed because the iobus has no default device by default.
* In the case of an fault injection the memory request could run over
* membus -> bridge -> iobus.
* If findport() in mem/bus.cc doesnt find a matching port on the iobus a default device is needed.
* This Device is configuered in fs.py and Device.py.
*/
class FailFakeDevice : public BasicPioDevice
{
protected:
uint8_t retData8;
uint16_t retData16;
uint32_t retData32;
uint64_t retData64;
public:
typedef FailFakeDeviceParams Params;
const Params *
params() const
{
return dynamic_cast<const Params *>(_params);
}
/**
* The constructor for FailFakeDevice just registers itself with the MMU.
* @param p params structure
*/
FailFakeDevice(Params *p);
/**
* This read always returns -1.
* @param pkt The memory request.
*/
virtual Tick read(PacketPtr pkt);
/**
* All writes are simply ignored.
* @param pkt The memory request.
*/
virtual Tick write(PacketPtr pkt);
};
#endif // __FAIL_FAKE__DEVICE_HH__