RAMpage experiment: basic client-side functionality complete

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1644 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
hsc
2012-09-13 23:17:44 +00:00
parent 55b94e9e17
commit c52988ea70
3 changed files with 102 additions and 42 deletions

View File

@ -34,19 +34,36 @@ using namespace fail;
bool RAMpageExperiment::run()
{
address_t addr1 = 1024*1024*62+3;
int bit1 = 3;
address_t addr2 = 1024*1024*63+8;
int bit2 = 5;
m_log << "startup" << std::endl;
// not implemented yet for QEMU:
//simulator.restore("rampage-cext-started");
MemWriteListener l_mem1(addr1);
MemoryManager& mm = simulator.getMemoryManager();
// We cannot include the auto-generated rampage.pb.h in experiment.hpp,
// because it is included in an aspect header; therefore we need to work
// around not having the type available there.
m_param = new RAMpageExperimentData;
#if LOCAL
//m_param->msg.set_mem_addr(1024*604+123);
m_param->msg.set_mem_addr(1024*1024*63+123);
m_param->msg.set_mem_bit(7);
m_param->msg.set_errortype(m_param->msg.ERROR_STUCK_AT_0);
m_param->msg.set_local_timeout(1000*60*10); // 10m
m_param->msg.set_global_timeout(1000*60*50); // 50m
#else
if (!m_jc.getm_param(m_param)) {
log << "Dying." << endl;
// communicate that we were told to die
simulator.terminate(1);
}
#endif
m_param->msg.set_mem_written(false);
MemWriteListener l_mem1(m_param->msg.mem_addr());
IOPortListener l_io(0x2f8, true); // ttyS1 aka COM2
TimerListener l_timeout_local(1000*60*10); // 10m
TimerListener l_timeout_global(1000*60*30); // 30m
TimerListener l_timeout_local(m_param->msg.local_timeout());
TimerListener l_timeout_global(m_param->msg.global_timeout());
simulator.addListener(&l_mem1);
simulator.addListener(&l_io);
@ -57,28 +74,8 @@ bool RAMpageExperiment::run()
if (l == &l_mem1) {
simulator.addListener(&l_mem1);
unsigned char data = mm.getByte(addr1);
#if 1
data |= 1 << bit1; // stuck-to-1
mm.setByte(addr1, data);
#elif 0
data &= ~(1 << bit1); // stuck-to-0
mm.setByte(addr1, data);
#elif 0
data &= ~(1 << bit2); // coupling bit2 := bit1
data |= ((data & (1 << bit1)) != 0) << bit2;
mm.setByte(addr1, data);
#elif 0
data &= ~(1 << bit2); // coupling bit2 := !bit1
data |= ((data & (1 << bit1)) == 0) << bit2;
mm.setByte(addr1, data);
#elif 0
unsigned char data2 = mm.getByte(addr2);
data2 &= ~(1 << bit2); // coupling addr2:bit2 := !addr1:bit1
data2 |= ((data & (1 << bit1)) == 0) << bit2;
mm.setByte(addr2, data2);
#endif
m_log << "access to addr 0x" << std::hex << addr1 << ", FI!" << endl;
handleMemWrite(l_mem1.getTriggerAddress());
m_param->msg.set_mem_written(true);
} else if (l == &l_io) {
simulator.addListener(&l_io);
if (handleIO(l_io.getData())) {
@ -88,14 +85,52 @@ bool RAMpageExperiment::run()
}
} else if (l == &l_timeout_local) {
m_log << "local timeout" << std::endl;
terminateExperiment(m_param->msg.LOCAL_TIMEOUT);
} else if (l == &l_timeout_global) {
m_log << "global timeout" << std::endl;
terminateExperiment(m_param->msg.GLOBAL_TIMEOUT);
}
}
return true;
}
void RAMpageExperiment::handleMemWrite(address_t addr)
{
address_t addr1 = addr;
unsigned bit1 = m_param->msg.mem_bit();
unsigned bit2 = m_param->msg.mem_coupled_bit();
unsigned char data = m_mm.getByte(addr1);
switch (m_param->msg.errortype()) {
case RAMpageProtoMsg::ERROR_NONE:
break;
case RAMpageProtoMsg::ERROR_STUCK_AT_0:
data &= ~(1 << bit1); // stuck-at-0
break;
case RAMpageProtoMsg::ERROR_STUCK_AT_1:
data |= 1 << bit1; // stuck-at-1
break;
case RAMpageProtoMsg::ERROR_COUPLING:
data &= ~(1 << bit2); // coupling bit2 := bit1
data |= ((data & (1 << bit1)) != 0) << bit2;
break;
case RAMpageProtoMsg::ERROR_INVERSE_COUPLING:
data &= ~(1 << bit2); // coupling bit2 := !bit1
data |= ((data & (1 << bit1)) == 0) << bit2;
break;
default:
m_log << "unknown error type" << std::endl;
}
m_mm.setByte(addr1, data);
m_log << "access to addr 0x" << std::hex << addr1 << ", FI!" << endl;
/*
unsigned char data2 = m_mm.getByte(addr2);
data2 &= ~(1 << bit2); // coupling addr2:bit2 := !addr1:bit1
data2 |= ((data & (1 << bit1)) == 0) << bit2;
m_mm.setByte(addr2, data2);
*/
}
bool RAMpageExperiment::handleIO(char c)
{
if (c != '\n') {
@ -105,34 +140,49 @@ bool RAMpageExperiment::handleIO(char c)
// calculating stats
if (!m_output.compare(0, sizeof(STR_STATS)-1, STR_STATS)) {
if (last_line_was_startingtestpass) {
if (m_last_line_was_startingtestpass) {
// result: NO_PFNS_TESTED
m_log << "no PFNs were tested this time" << std::endl;
simulator.terminate();
terminateExperiment(m_param->msg.NO_PFNS_TESTED);
}
m_log << STR_STATS << std::endl;
// starting test pass
} else if (!m_output.compare(0, sizeof(STR_START)-1, STR_START)) {
last_line_was_startingtestpass = true;
m_last_line_was_startingtestpass = true;
m_log << STR_START << std::endl;
// tested %08x-%08x %08x-%08x ...
} else if (!m_output.compare(0, sizeof(STR_TESTED)-1, STR_TESTED)) {
last_line_was_startingtestpass = false;
m_last_line_was_startingtestpass = false;
m_log << STR_TESTED << std::endl;
// TODO test whether the failing PFN was listed
//terminateExperiment(m_param->msg.PFN_WAS_LISTED);
// bad frame at pfn %08x
} else if (!m_output.compare(0, sizeof(STR_BADFRAME)-1, STR_BADFRAME)) {
m_log << STR_BADFRAME << std::endl;
simulator.terminate();
// TODO test whether it was the right PFN
terminateExperiment(m_param->msg.RIGHT_PFN_DETECTED);
} else {
// unknown
m_log << "wtf unknown: " << m_output << std::endl;
simulator.terminate();
m_param->msg.set_details("unknown serial output: " + m_output);
terminateExperiment(m_param->msg.UNKNOWN);
}
m_output.clear();
return true;
}
void RAMpageExperiment::terminateExperiment(int resulttype)
{
m_param->msg.set_resulttype((RAMpageProtoMsg::ResultType) resulttype);
// TODO measure time
#if !LOCAL
m_jc.sendResult(param);
#endif
simulator.terminate();
}

View File

@ -3,19 +3,28 @@
#include <string>
#include "sal/SALConfig.hpp"
#include "efw/ExperimentFlow.hpp"
#include "efw/JobClient.hpp"
#include "util/Logger.hpp"
class RAMpageExperimentData;
class RAMpageExperiment : public fail::ExperimentFlow {
fail::JobClient m_jc;
fail::Logger m_log;
std::string m_output;
bool last_line_was_startingtestpass;
bool m_last_line_was_startingtestpass;
fail::MemoryManager& m_mm;
RAMpageExperimentData *m_param;
void handleMemWrite(fail::address_t addr);
bool handleIO(char c);
void terminateExperiment(int resulttype);
public:
RAMpageExperiment() : m_log("RAMpage"), last_line_was_startingtestpass(false) {}
RAMpageExperiment()
: m_log("RAMpage"), m_last_line_was_startingtestpass(false),
m_mm(fail::simulator.getMemoryManager()) {}
bool run();
};

View File

@ -13,19 +13,20 @@ message RAMpageProtoMsg {
ERROR_STUCK_AT_0 = 2;
ERROR_STUCK_AT_1 = 3;
ERROR_COUPLING = 4;
ERROR_INVERSE_COUPLING = 5;
}
required ErrorType errortype = 4;
// local timeout (between newlines on ttyS1)
optional int32 local_timeout = 5;
required int32 local_timeout = 5;
// global timeout
optional int32 global_timeout = 6;
required int32 global_timeout = 6;
// ----------------------------------------------------
// Output: experiment results
// erroneous byte was written to
required bool mem_written = 8;
optional bool mem_written = 8;
enum ResultType {
RIGHT_PFN_DETECTED = 1;
@ -45,7 +46,7 @@ message RAMpageProtoMsg {
// pfn the error was detected in (hopefully the right one?)
optional int32 error_detected_pfn = 10;
// host wallclock time it took until we finished
required int32 experiment_time = 11;
optional int32 experiment_time = 11;
// debugging info
optional string details = 12;