diff --git a/src/experiments/rampage/CMakeLists.txt b/src/experiments/rampage/CMakeLists.txt new file mode 100644 index 00000000..5c12ad47 --- /dev/null +++ b/src/experiments/rampage/CMakeLists.txt @@ -0,0 +1,31 @@ +set(EXPERIMENT_NAME rampage) +set(EXPERIMENT_TYPE RAMpageExperiment) +configure_file(../instantiate-experiment.ah.in + ${CMAKE_CURRENT_BINARY_DIR}/instantiate-${EXPERIMENT_NAME}.ah @ONLY +) + +set(MY_PROTOS + rampage.proto +) + +set(MY_CAMPAIGN_SRCS + experiment.hpp + experiment.cc + campaign.hpp + campaign.cc +) + +#### PROTOBUFS #### +find_package(Protobuf REQUIRED) +include_directories(${PROTOBUF_INCLUDE_DIRS}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS}) + +## Build library +add_library(fail-${EXPERIMENT_NAME} ${PROTO_SRCS} ${PROTO_HDRS} ${MY_CAMPAIGN_SRCS}) + +## This is the example's campaign server distributing experiment parameters +add_executable(${EXPERIMENT_NAME}-server main.cc) +target_link_libraries(${EXPERIMENT_NAME}-server fail-${EXPERIMENT_NAME} fail) +install(TARGETS ${EXPERIMENT_NAME}-server RUNTIME DESTINATION bin) diff --git a/src/experiments/rampage/campaign.cc b/src/experiments/rampage/campaign.cc new file mode 100644 index 00000000..25de0152 --- /dev/null +++ b/src/experiments/rampage/campaign.cc @@ -0,0 +1,16 @@ +#include + +#include "campaign.hpp" +#include "cpn/CampaignManager.hpp" +#include "util/Logger.hpp" + +using namespace std; +using namespace fail; + +char const * const results_filename = "rampage.csv"; + +bool RAMpageCampaign::run() +{ + // TODO + return true; +} diff --git a/src/experiments/rampage/campaign.hpp b/src/experiments/rampage/campaign.hpp new file mode 100644 index 00000000..b797e86e --- /dev/null +++ b/src/experiments/rampage/campaign.hpp @@ -0,0 +1,19 @@ +#ifndef __RAMPAGE_CAMPAIGN_HPP__ + #define __RAMPAGE_CAMPAIGN_HPP__ + +#include "cpn/Campaign.hpp" +#include "comm/ExperimentData.hpp" +#include "rampage.pb.h" + +class RAMpageExperimentData : public fail::ExperimentData { +public: + RAMpageProtoMsg msg; + RAMpageExperimentData() : fail::ExperimentData(&msg) {} +}; + +class RAMpageCampaign : public fail::Campaign { +public: + virtual bool run(); +}; + +#endif // __RAMPAGE_CAMPAIGN_HPP__ diff --git a/src/experiments/rampage/experiment.cc b/src/experiments/rampage/experiment.cc new file mode 100644 index 00000000..6c6a8f66 --- /dev/null +++ b/src/experiments/rampage/experiment.cc @@ -0,0 +1,98 @@ +#include + +// getpid +#include +#include + +#include "util/Logger.hpp" + +#include "experiment.hpp" +#include "campaign.hpp" + +#include "sal/SALConfig.hpp" +#include "sal/SALInst.hpp" +#include "sal/Memory.hpp" +#include "sal/Listener.hpp" + +#define LOCAL 1 + +using namespace std; +using namespace fail; + +/* +// Check if configuration dependencies are satisfied: +#if !defined(CONFIG_EVENT_BREAKPOINTS) || !defined(CONFIG_SR_RESTORE) || \ + !defined(CONFIG_SR_SAVE) || !defined(CONFIG_EVENT_TRAP) + #error This experiment needs: breakpoints, traps, save, and restore. Enable these in the configuration. +#endif +*/ + +bool RAMpageExperiment::run() +{ + Logger log("RAMpage", false); + address_t addr1 = 1024*1024*62+3; + int bit1 = 3; + address_t addr2 = 1024*1024*63+8; + int bit2 = 5; + + // not implemented yet for QEMU: + //simulator.restore("rampage-cext-started"); + + // TODO: Timeout + // TODO: Serial + + MemWriteListener l_mem1(addr1); + MemoryManager& mm = simulator.getMemoryManager(); + while (true) { + simulator.addListener(&l_mem1); + simulator.resume(); + 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 + log << "access to addr 0x" << std::hex << addr1 << ", FI!" << endl; + } + + /* + MemWriteListener l_mem2(addr2); + + log << "startup" << endl; + + simulator.addListener(&l_mem1); + simulator.addListener(&l_mem2); + + while (true) { + MemWriteListener *l = static_cast(simulator.resume()); + simulator.addListener(l); + + address_t target; + + if (l == &l_mem1) { + target = addr2; + } else { + target = addr1; + } + + unsigned char data = simulator.getMemoryManager().getByte(l->getWatchAddress()); + data ^= ( + } + */ + return true; +} diff --git a/src/experiments/rampage/experiment.hpp b/src/experiments/rampage/experiment.hpp new file mode 100644 index 00000000..7522d0cd --- /dev/null +++ b/src/experiments/rampage/experiment.hpp @@ -0,0 +1,13 @@ +#ifndef __RAMPAGE_EXPERIMENT_HPP__ + #define __RAMPAGE_EXPERIMENT_HPP__ + +#include "efw/ExperimentFlow.hpp" +#include "efw/JobClient.hpp" + +class RAMpageExperiment : public fail::ExperimentFlow { + fail::JobClient m_jc; +public: + bool run(); +}; + +#endif // __RAMPAGE_EXPERIMENT_HPP__ diff --git a/src/experiments/rampage/main.cc b/src/experiments/rampage/main.cc new file mode 100644 index 00000000..119914cb --- /dev/null +++ b/src/experiments/rampage/main.cc @@ -0,0 +1,11 @@ +#include +#include + +#include "cpn/CampaignManager.hpp" +#include "campaign.hpp" + +int main(int argc, char **argv) +{ + RAMpageCampaign c; + return !fail::campaignmanager.runCampaign(&c); +} diff --git a/src/experiments/rampage/rampage.proto b/src/experiments/rampage/rampage.proto new file mode 100644 index 00000000..5f04eea6 --- /dev/null +++ b/src/experiments/rampage/rampage.proto @@ -0,0 +1,40 @@ +message RAMpageProtoMsg { + // Input: experiment parameters + + // memory error address + required int64 mem_addr = 1; + // failing bit at that address + required int32 mem_bit = 2; + // coupled bit at that address (only for ERROR_COUPLING) + optional int32 mem_coupled_bit = 3; + // error type + enum ErrorType { + ERROR_NONE = 1; + ERROR_STUCK_AT_0 = 2; + ERROR_STUCK_AT_1 = 3; + ERROR_COUPLING = 4; + } + required ErrorType errortype = 4; + // global timeout + optional int32 timeout = 5; + + // ---------------------------------------------------- + + // Output: experiment results + + // erroneous byte was written to + required bool mem_written = 8; + // erroneous pfn was listed on the serial line + required bool pfn_listed = 9; + // error detected ("bad pfn at ...") + required bool error_detected = 10; + // pfn the error was detected in (hopefully the right one?) + required int32 error_detected_pfn = 11; + // global timeout was reached + required bool timeout_reached = 12; + // host wallclock time it took until we finished + required int32 experiment_time = 13; + + // debugging info + optional string details = 14; +}