ecos_kernel_test: merge experiment steps 0-2 into a single run
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1443 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
@ -12,8 +12,6 @@
|
|||||||
#include "util/ProtoStream.hpp"
|
#include "util/ProtoStream.hpp"
|
||||||
#include "util/MemoryMap.hpp"
|
#include "util/MemoryMap.hpp"
|
||||||
|
|
||||||
#include "ecc_region.hpp"
|
|
||||||
|
|
||||||
#include "../plugins/tracing/TracingPlugin.hpp"
|
#include "../plugins/tracing/TracingPlugin.hpp"
|
||||||
|
|
||||||
//#define PRUNING_DEBUG_OUTPUT
|
//#define PRUNING_DEBUG_OUTPUT
|
||||||
@ -23,6 +21,29 @@ using namespace fail;
|
|||||||
|
|
||||||
char const * const trace_filename = "trace.tc";
|
char const * const trace_filename = "trace.tc";
|
||||||
char const * const results_filename = "ecos_kernel_test.csv";
|
char const * const results_filename = "ecos_kernel_test.csv";
|
||||||
|
char const * const mm_filename = "memory_map.txt"; //TODO: sync with experiment.cc
|
||||||
|
|
||||||
|
bool EcosKernelTestCampaign::readMemoryMap(fail::MemoryMap &mm, char const * const filename) {
|
||||||
|
ifstream file(filename);
|
||||||
|
if (!file.is_open()) {
|
||||||
|
cout << "failed to open " << filename << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string buf;
|
||||||
|
stringstream ss(ios::in);
|
||||||
|
unsigned guest_addr, guest_len;
|
||||||
|
unsigned count = 0;
|
||||||
|
|
||||||
|
while (getline(file, buf)) {
|
||||||
|
ss.str(buf);
|
||||||
|
ss >> guest_addr >> guest_len;
|
||||||
|
mm.add(guest_addr, guest_len);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
return (count > 0);
|
||||||
|
}
|
||||||
|
|
||||||
// equivalence class type: addr, [i1, i2]
|
// equivalence class type: addr, [i1, i2]
|
||||||
// addr: byte to inject a bit-flip into
|
// addr: byte to inject a bit-flip into
|
||||||
@ -60,9 +81,7 @@ bool EcosKernelTestCampaign::run()
|
|||||||
|
|
||||||
// a map of addresses of ECC protected objects
|
// a map of addresses of ECC protected objects
|
||||||
MemoryMap mm;
|
MemoryMap mm;
|
||||||
for (unsigned i = 0; i < sizeof(memoryMap)/sizeof(*memoryMap); ++i) {
|
EcosKernelTestCampaign::readMemoryMap(mm, mm_filename);
|
||||||
mm.add(memoryMap[i][0], memoryMap[i][1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set of equivalence classes that need one (rather: eight, one for
|
// set of equivalence classes that need one (rather: eight, one for
|
||||||
// each bit in that byte) experiment to determine them all
|
// each bit in that byte) experiment to determine them all
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include "cpn/Campaign.hpp"
|
#include "cpn/Campaign.hpp"
|
||||||
#include "comm/ExperimentData.hpp"
|
#include "comm/ExperimentData.hpp"
|
||||||
#include "ecos_kernel_test.pb.h"
|
#include "ecos_kernel_test.pb.h"
|
||||||
|
#include "util/MemoryMap.hpp"
|
||||||
|
|
||||||
class EcosKernelTestExperimentData : public fail::ExperimentData {
|
class EcosKernelTestExperimentData : public fail::ExperimentData {
|
||||||
public:
|
public:
|
||||||
@ -13,5 +14,6 @@ public:
|
|||||||
class EcosKernelTestCampaign : public fail::Campaign {
|
class EcosKernelTestCampaign : public fail::Campaign {
|
||||||
public:
|
public:
|
||||||
virtual bool run();
|
virtual bool run();
|
||||||
|
static bool readMemoryMap(fail::MemoryMap &mm, char const * const filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,82 +0,0 @@
|
|||||||
// generated from STEP 0 output with region2array.sh
|
|
||||||
static const unsigned memoryMap[][2] = {
|
|
||||||
{0x9bec, 4},
|
|
||||||
{0xade0, 4},
|
|
||||||
{0xade4, 4},
|
|
||||||
{0xade8, 4},
|
|
||||||
{0xadf0, 4},
|
|
||||||
{0xadf4, 4},
|
|
||||||
{0xadf8, 4},
|
|
||||||
{0xadfc, 4},
|
|
||||||
{0xae00, 4},
|
|
||||||
{0xae04, 4},
|
|
||||||
{0xae08, 4},
|
|
||||||
{0xae0c, 4},
|
|
||||||
{0xae10, 4},
|
|
||||||
{0xae14, 2},
|
|
||||||
{0xae44, 4},
|
|
||||||
{0xae48, 4},
|
|
||||||
{0xae4c, 24},
|
|
||||||
{0xae64, 4},
|
|
||||||
{0xae68, 4},
|
|
||||||
{0xae6c, 4},
|
|
||||||
{0xae70, 4},
|
|
||||||
{0xae74, 4},
|
|
||||||
{0xae7c, 4},
|
|
||||||
{0xae80, 4},
|
|
||||||
{0xae84, 4},
|
|
||||||
{0xae88, 4},
|
|
||||||
{0xae8c, 4},
|
|
||||||
{0xae90, 4},
|
|
||||||
{0xae94, 4},
|
|
||||||
{0xae98, 4},
|
|
||||||
{0xae9c, 4},
|
|
||||||
{0xaea0, 2},
|
|
||||||
{0xaed0, 4},
|
|
||||||
{0xaed4, 4},
|
|
||||||
{0xaed8, 24},
|
|
||||||
{0xaef0, 4},
|
|
||||||
{0xaef4, 4},
|
|
||||||
{0xca48, 4},
|
|
||||||
{0xca60, 4},
|
|
||||||
{0xca64, 4},
|
|
||||||
{0xca68, 4},
|
|
||||||
{0xca70, 4},
|
|
||||||
{0xca74, 4},
|
|
||||||
{0xca78, 4},
|
|
||||||
{0xca7c, 4},
|
|
||||||
{0xca80, 4},
|
|
||||||
{0xca84, 4},
|
|
||||||
{0xca88, 4},
|
|
||||||
{0xca8c, 4},
|
|
||||||
{0xca90, 4},
|
|
||||||
{0xca94, 2},
|
|
||||||
{0xcac4, 4},
|
|
||||||
{0xcac8, 4},
|
|
||||||
{0xcacc, 24},
|
|
||||||
{0xcae4, 4},
|
|
||||||
{0xcae8, 4},
|
|
||||||
{0xd314, 4},
|
|
||||||
{0xd318, 4},
|
|
||||||
{0xd320, 4},
|
|
||||||
{0xd324, 128},
|
|
||||||
{0xd3a4, 4},
|
|
||||||
{0xd3c0, 4},
|
|
||||||
{0xd3c4, 4},
|
|
||||||
{0xd3c8, 4},
|
|
||||||
{0xd3d0, 4},
|
|
||||||
{0xd3d4, 4},
|
|
||||||
{0xd3d8, 4},
|
|
||||||
{0xd3dc, 4},
|
|
||||||
{0xd3e0, 4},
|
|
||||||
{0xd3e4, 4},
|
|
||||||
{0xd3e8, 4},
|
|
||||||
{0xd3ec, 4},
|
|
||||||
{0xd3f0, 4},
|
|
||||||
{0xd3f4, 2},
|
|
||||||
{0xd424, 4},
|
|
||||||
{0xd428, 4},
|
|
||||||
{0xd42c, 24},
|
|
||||||
{0xd444, 4},
|
|
||||||
{0xd448, 4},
|
|
||||||
};
|
|
||||||
@ -1,5 +1,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
//#include <string>
|
||||||
|
|
||||||
// getpid
|
// getpid
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -19,8 +20,6 @@
|
|||||||
// You need to have the tracing plugin enabled for this
|
// You need to have the tracing plugin enabled for this
|
||||||
#include "../plugins/tracing/TracingPlugin.hpp"
|
#include "../plugins/tracing/TracingPlugin.hpp"
|
||||||
|
|
||||||
#include "ecc_region.hpp"
|
|
||||||
|
|
||||||
#define LOCAL 0
|
#define LOCAL 0
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -32,6 +31,9 @@ using namespace fail;
|
|||||||
#error This experiment needs: breakpoints, traps, save, and restore. Enable these in the configuration.
|
#error This experiment needs: breakpoints, traps, save, and restore. Enable these in the configuration.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
char const * const mm_filename = "memory_map.txt";
|
||||||
|
|
||||||
bool EcosKernelTestExperiment::run()
|
bool EcosKernelTestExperiment::run()
|
||||||
{
|
{
|
||||||
char const *statename = "ecos_kernel_test.state";
|
char const *statename = "ecos_kernel_test.state";
|
||||||
@ -40,88 +42,160 @@ bool EcosKernelTestExperiment::run()
|
|||||||
|
|
||||||
log << "startup" << endl;
|
log << "startup" << endl;
|
||||||
|
|
||||||
#if 0
|
log << "STEP 0: record memory map with addresses of 'interesting' objects" << endl;
|
||||||
// STEP 0: record memory map with addresses of "interesting" objects
|
{
|
||||||
GuestEvent g;
|
// workaround for 00002808875p[BIOS ] >>PANIC<< Keyboard error:21
|
||||||
while (true) {
|
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||||
simulator.addEventAndWait(&g);
|
simulator.addEventAndWait(&bp);
|
||||||
cout << g.getData() << flush;
|
|
||||||
|
GuestEvent g;
|
||||||
|
simulator.addEvent(&g);
|
||||||
|
|
||||||
|
// 10000us = 500000 instructions
|
||||||
|
TimerEvent record_timeout(50000000); //TODO: how long to wait?
|
||||||
|
simulator.addEvent(&record_timeout);
|
||||||
|
|
||||||
|
// memory map serialization
|
||||||
|
ofstream mm(mm_filename, ios::out | ios::app);
|
||||||
|
if (!mm.is_open()) {
|
||||||
|
log << "failed to open " << mm_filename << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string *str = new string; // buffer for guest events
|
||||||
|
unsigned number_of_guest_events = 0;
|
||||||
|
|
||||||
|
while (simulator.waitAny() != &record_timeout) {
|
||||||
|
simulator.addEvent(&g);
|
||||||
|
str->push_back(g.getData());
|
||||||
|
|
||||||
|
if (g.getData() == '\t') {
|
||||||
|
// addr complete?
|
||||||
|
//cout << "full: " << *str << "sub: " << str->substr(str->find_last_of('x') - 1) << endl;
|
||||||
|
// interpret the string obtained by the guest events as address in hex
|
||||||
|
unsigned guest_addr;
|
||||||
|
stringstream converter(str->substr(str->find_last_of('x') + 1));
|
||||||
|
converter >> hex >> guest_addr;
|
||||||
|
mm << guest_addr << '\t';
|
||||||
|
str->clear();
|
||||||
|
} else if (g.getData() == '\n') {
|
||||||
|
// len complete?
|
||||||
|
// interpret the string obtained by the guest events as length in decimal
|
||||||
|
unsigned guest_len;
|
||||||
|
stringstream converter(*str);
|
||||||
|
converter >> dec >> guest_len;
|
||||||
|
mm << guest_len << '\n';
|
||||||
|
str->clear();
|
||||||
|
number_of_guest_events++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(number_of_guest_events > 0);
|
||||||
|
cout << "Record timeout reached: created memory map (" << number_of_guest_events << " entries)" << endl;
|
||||||
|
delete str;
|
||||||
|
|
||||||
|
// close serialized mm
|
||||||
|
mm.flush();
|
||||||
|
mm.close();
|
||||||
|
|
||||||
|
// clean up simulator and reboot the guest system
|
||||||
|
simulator.clearEvents();
|
||||||
|
log << "rebooting ..." << endl;
|
||||||
|
simulator.reboot();
|
||||||
}
|
}
|
||||||
#elif 0
|
|
||||||
// STEP 1: run until interesting function starts, and save state
|
|
||||||
bp.setWatchInstructionPointer(ECOS_FUNC_ENTRY);
|
|
||||||
simulator.addEventAndWait(&bp);
|
|
||||||
log << "test function entry reached, saving state" << endl;
|
|
||||||
log << "EIP = " << hex << bp.getTriggerInstructionPointer() << endl;
|
|
||||||
//log << "error_corrected = " << dec << ((int)simulator.getMemoryManager().getByte(OOSTUBS_ERROR_CORRECTED)) << endl;
|
|
||||||
simulator.save(statename);
|
|
||||||
assert(bp.getTriggerInstructionPointer() == ECOS_FUNC_ENTRY);
|
|
||||||
assert(simulator.getRegisterManager().getInstructionPointer() == ECOS_FUNC_ENTRY);
|
|
||||||
#elif 0
|
|
||||||
// STEP 2: record trace for fault-space pruning
|
|
||||||
log << "restoring state" << endl;
|
|
||||||
simulator.restore(statename);
|
|
||||||
log << "EIP = " << hex << simulator.getRegisterManager().getInstructionPointer() << endl;
|
|
||||||
assert(simulator.getRegisterManager().getInstructionPointer() == ECOS_FUNC_ENTRY);
|
|
||||||
|
|
||||||
log << "enabling tracing" << endl;
|
log << "STEP 1: run until interesting function starts, and save state" << endl;
|
||||||
TracingPlugin tp;
|
{
|
||||||
|
GuestEvent g;
|
||||||
|
|
||||||
// restrict memory access logging to injection target
|
while (true) {
|
||||||
MemoryMap mm;
|
simulator.addEventAndWait(&g);
|
||||||
for (unsigned i = 0; i < sizeof(memoryMap)/sizeof(*memoryMap); ++i) {
|
if(g.getData() == 'Q') {
|
||||||
mm.add(memoryMap[i][0], memoryMap[i][1]);
|
cout << "Guest system triggered: " << g.getData() << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bp.setWatchInstructionPointer(ECOS_FUNC_ENTRY);
|
||||||
|
simulator.addEventAndWait(&bp);
|
||||||
|
log << "test function entry reached, saving state" << endl;
|
||||||
|
log << "EIP = " << hex << bp.getTriggerInstructionPointer() << endl;
|
||||||
|
//log << "error_corrected = " << dec << ((int)simulator.getMemoryManager().getByte(OOSTUBS_ERROR_CORRECTED)) << endl;
|
||||||
|
simulator.save(statename);
|
||||||
|
assert(bp.getTriggerInstructionPointer() == ECOS_FUNC_ENTRY);
|
||||||
|
assert(simulator.getRegisterManager().getInstructionPointer() == ECOS_FUNC_ENTRY);
|
||||||
|
|
||||||
|
// clean up simulator and reboot the guest system
|
||||||
|
simulator.clearEvents();
|
||||||
|
log << "rebooting ..." << endl;
|
||||||
|
simulator.reboot();
|
||||||
}
|
}
|
||||||
tp.restrictMemoryAddresses(&mm);
|
|
||||||
|
|
||||||
// record trace
|
log << "STEP 2: record trace for fault-space pruning" << endl;
|
||||||
char const *tracefile = "trace.tc";
|
{
|
||||||
ofstream of(tracefile);
|
log << "restoring state" << endl;
|
||||||
tp.setTraceFile(&of);
|
simulator.restore(statename);
|
||||||
|
log << "EIP = " << hex << simulator.getRegisterManager().getInstructionPointer() << endl;
|
||||||
|
assert(simulator.getRegisterManager().getInstructionPointer() == ECOS_FUNC_ENTRY);
|
||||||
|
|
||||||
// this must be done *after* configuring the plugin:
|
log << "enabling tracing" << endl;
|
||||||
simulator.addFlow(&tp);
|
TracingPlugin tp;
|
||||||
|
|
||||||
|
// restrict memory access logging to injection target
|
||||||
|
MemoryMap mm;
|
||||||
|
EcosKernelTestCampaign::readMemoryMap(mm, mm_filename);
|
||||||
|
|
||||||
|
tp.restrictMemoryAddresses(&mm);
|
||||||
|
|
||||||
|
// record trace
|
||||||
|
char const *tracefile = "trace.tc";
|
||||||
|
ofstream of(tracefile);
|
||||||
|
tp.setTraceFile(&of);
|
||||||
|
|
||||||
|
// this must be done *after* configuring the plugin:
|
||||||
|
simulator.addFlow(&tp);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// trace WEATHER_NUMITER_TRACING measurement loop iterations
|
// trace WEATHER_NUMITER_TRACING measurement loop iterations
|
||||||
// -> calibration
|
// -> calibration
|
||||||
bp.setWatchInstructionPointer(ECOS_FUNC_FINISH);
|
bp.setWatchInstructionPointer(ECOS_FUNC_FINISH);
|
||||||
//bp.setCounter(WEATHER_NUMITER_TRACING); // single event, only
|
//bp.setCounter(WEATHER_NUMITER_TRACING); // single event, only
|
||||||
#else
|
#else
|
||||||
// FIXME this doesn't work properly: trace is one instruction too short as
|
// FIXME this doesn't work properly: trace is one instruction too short as
|
||||||
// tp is removed before all events were delivered
|
// tp is removed before all events were delivered
|
||||||
// trace WEATHER_NUMINSTR_TRACING instructions
|
// trace WEATHER_NUMINSTR_TRACING instructions
|
||||||
// -> campaign-ready traces with identical lengths
|
// -> campaign-ready traces with identical lengths
|
||||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||||
bp.setCounter(OOSTUBS_NUMINSTR);
|
bp.setCounter(OOSTUBS_NUMINSTR);
|
||||||
#endif
|
#endif
|
||||||
simulator.addEvent(&bp);
|
simulator.addEvent(&bp);
|
||||||
BPSingleEvent ev_count(ANY_ADDR);
|
BPSingleEvent ev_count(ANY_ADDR);
|
||||||
simulator.addEvent(&ev_count);
|
|
||||||
|
|
||||||
// count instructions
|
|
||||||
// FIXME add SAL functionality for this?
|
|
||||||
int instr_counter = 0;
|
|
||||||
while (simulator.waitAny() == &ev_count) {
|
|
||||||
++instr_counter;
|
|
||||||
simulator.addEvent(&ev_count);
|
simulator.addEvent(&ev_count);
|
||||||
|
|
||||||
|
// count instructions
|
||||||
|
// FIXME add SAL functionality for this?
|
||||||
|
int instr_counter = 0;
|
||||||
|
while (simulator.waitAny() == &ev_count) {
|
||||||
|
++instr_counter;
|
||||||
|
simulator.addEvent(&ev_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
log << dec << "tracing finished after " << instr_counter << " instructions" << endl;
|
||||||
|
//TODO: safe this value for experiment STEP 3
|
||||||
|
|
||||||
|
|
||||||
|
simulator.removeFlow(&tp);
|
||||||
|
|
||||||
|
// serialize trace to file
|
||||||
|
if (of.fail()) {
|
||||||
|
log << "failed to write " << tracefile << endl;
|
||||||
|
simulator.clearEvents(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
of.close();
|
||||||
|
log << "trace written to " << tracefile << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
log << dec << "tracing finished after " << instr_counter << " instructions" << endl;
|
#if 0
|
||||||
|
|
||||||
|
|
||||||
simulator.removeFlow(&tp);
|
|
||||||
|
|
||||||
// serialize trace to file
|
|
||||||
if (of.fail()) {
|
|
||||||
log << "failed to write " << tracefile << endl;
|
|
||||||
simulator.clearEvents(this);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
of.close();
|
|
||||||
log << "trace written to " << tracefile << endl;
|
|
||||||
|
|
||||||
#elif 1
|
|
||||||
// STEP 3: The actual experiment.
|
// STEP 3: The actual experiment.
|
||||||
#if !LOCAL
|
#if !LOCAL
|
||||||
for (int i = 0; i < 400; ++i) { // more than 400 will be very slow (500 is max)
|
for (int i = 0; i < 400; ++i) { // more than 400 will be very slow (500 is max)
|
||||||
|
|||||||
@ -1,40 +1,28 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// FIXME autogenerate this
|
// autogenerated, don't edit!
|
||||||
|
|
||||||
#if 1 // with ECC
|
// user-specified start-function address:
|
||||||
|
// nm -C thread1.elf|fgrep cyg_start
|
||||||
|
#define ECOS_FUNC_ENTRY 0x0000406c
|
||||||
|
// cyg_test_exit address
|
||||||
|
#define ECOS_FUNC_FINISH 0x00005eb0
|
||||||
|
// cyg_test_output address
|
||||||
|
#define ECOS_FUNC_TEST_OUTPUT 0x00005eb8
|
||||||
|
// the variable that's increased if ECC corrects an error:
|
||||||
|
#define ECOS_ERROR_CORRECTED 0x99999999
|
||||||
|
|
||||||
// the task function's entry address:
|
// text begin:
|
||||||
// nm -C thread1 | fgrep cyg_start
|
// nm -C thread1.elf|fgrep _stext
|
||||||
#define ECOS_FUNC_ENTRY 0x00003cc0
|
#define ECOS_TEXT_START 0x00003000
|
||||||
// empty function that is called explicitly when the experiment finished
|
// text end:
|
||||||
// nm -C thread1 | fgrep cyg_test_exit
|
// nm -C thread1.elf|fgrep _etext
|
||||||
#define ECOS_FUNC_FINISH 0x000058dc
|
#define ECOS_TEXT_END 0x00013c9e
|
||||||
// nm -C thread1 | fgrep "cyg_test_output"
|
|
||||||
#define ECOS_FUNC_TEST_OUTPUT 0x000058e4
|
|
||||||
|
|
||||||
// nm -C thread1 | grep "_[se]text"
|
// number of instructions the target executes under non-error conditions from ENTRY to FINISH:
|
||||||
#define ECOS_TEXT_START 0x00003000
|
#define ECOS_NUMINSTR 71618
|
||||||
#define ECOS_TEXT_END 0x000092ce
|
|
||||||
|
|
||||||
// number of instructions the target executes under non-error conditions from ENTRY to DONE:
|
|
||||||
// (result of experiment's step #2)
|
|
||||||
#define ECOS_NUMINSTR 12390
|
|
||||||
// number of instructions that are executed additionally for error corrections
|
// number of instructions that are executed additionally for error corrections
|
||||||
// (this is a rough guess ... TODO)
|
// (this is a rough guess ... TODO)
|
||||||
#define ECOS_RECOVERYINSTR 0x2000
|
#define ECOS_RECOVERYINSTR 0x2000
|
||||||
// the variable that's increased if ECC corrects an error:
|
|
||||||
// nm -C thread1|fgrep errors_corrected
|
|
||||||
#define ECOS_ERROR_CORRECTED 0x0010adec //FIXME TODO XXX
|
|
||||||
|
|
||||||
#else // without ECC
|
|
||||||
|
|
||||||
#define COOL_ECC_FUNC_ENTRY 0x00200a90
|
|
||||||
#define COOL_ECC_CALCDONE 0x00200ab7
|
|
||||||
#define COOL_ECC_NUMINSTR 97
|
|
||||||
#define COOL_ECC_OBJUNDERTEST 0x0021263c
|
|
||||||
#define COOL_ECC_OBJUNDERTEST_SIZE 10
|
|
||||||
#define COOL_ECC_ERROR_CORRECTED 0x002127b0 // dummy
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|||||||
47
src/experiments/ecos_kernel_test/experimentInfo.hpp.sh
Executable file
47
src/experiments/ecos_kernel_test/experimentInfo.hpp.sh
Executable file
@ -0,0 +1,47 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
TARGET=experimentInfo.hpp
|
||||||
|
|
||||||
|
[ ! -e "$1" ] && echo "usage: $0 ecos_binary.elf" && exit 1
|
||||||
|
|
||||||
|
function addrof() { nm -C $1 | (fgrep "$2" || echo 99999999) | awk '{print $1}'; }
|
||||||
|
|
||||||
|
cat >$TARGET <<EOF
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// autogenerated, don't edit!
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
function alldefs() {
|
||||||
|
cat <<EOF
|
||||||
|
// user-specified start-function address:
|
||||||
|
// nm -C $(basename $1)|fgrep cyg_start
|
||||||
|
#define ECOS_FUNC_ENTRY 0x`addrof $1 cyg_start`
|
||||||
|
// cyg_test_exit address
|
||||||
|
#define ECOS_FUNC_FINISH 0x`addrof $1 cyg_test_exit`
|
||||||
|
// cyg_test_output address
|
||||||
|
#define ECOS_FUNC_TEST_OUTPUT 0x`addrof $1 cyg_test_output`
|
||||||
|
// the variable that's increased if ECC corrects an error:
|
||||||
|
#define ECOS_ERROR_CORRECTED 0x`addrof $1 errors_corrected`
|
||||||
|
|
||||||
|
// text begin:
|
||||||
|
// nm -C $(basename $1)|fgrep _stext
|
||||||
|
#define ECOS_TEXT_START 0x`addrof $1 _stext`
|
||||||
|
// text end:
|
||||||
|
// nm -C $(basename $1)|fgrep _etext
|
||||||
|
#define ECOS_TEXT_END 0x`addrof $1 _etext`
|
||||||
|
|
||||||
|
// number of instructions the target executes under non-error conditions from ENTRY to FINISH:
|
||||||
|
#define ECOS_NUMINSTR 71618
|
||||||
|
// number of instructions that are executed additionally for error corrections
|
||||||
|
// (this is a rough guess ... TODO)
|
||||||
|
#define ECOS_RECOVERYINSTR 0x2000
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
alldefs $1 >>$TARGET
|
||||||
|
cat >>$TARGET <<EOF
|
||||||
|
|
||||||
|
|
||||||
|
EOF
|
||||||
Reference in New Issue
Block a user