#include #include #include #include "memtest.hpp" /* * */ template class Generator { public: Generator(void) : pattern(0) {;} virtual T get(void) = 0; virtual void init(T seed) { pattern = seed; } protected: T pattern; }; /* * */ template class GeneratorWalkingOne : public Generator { T get(void) { T ret = this->pattern; this->pattern <<= 1; if (0 == this->pattern) this->pattern = 1; return ret; } }; /* * */ template class GeneratorWalkingZero : public Generator { T get(void) { T ret = ~this->pattern; this->pattern <<= 1; if (0 == this->pattern) this->pattern = 1; return ret; } }; /* * */ template class GeneratorOwnAddress : public Generator { T get(void) { T ret = this->pattern; this->pattern++; return ret; } }; /* * */ template class GeneratorMovingInv : public Generator { T get(void) { T ret = this->pattern; this->pattern = ~this->pattern; return ret; } }; /* * */ template class GeneratorMovingInvRand : public Generator { public: GeneratorMovingInvRand(void) : step(0), prev(0){;} void init(T seed) { srand(seed); step = 0; prev = 0; } T get(void) { T ret; T mask = -1; if ((step & 1) == 0) { ret = rand() & mask; prev = ret; } else { ret = ~prev & mask; } step++; return ret; } private: size_t step; T prev; }; /* * */ template static void memtest_sequential(memtest_t *memp, Generator &generator, T seed) { const size_t steps = memp->size / sizeof(T); size_t i; T *mem = static_cast(memp->start); /* fill ram */ generator.init(seed); for (i=0; iecb(memp, MEMTEST_WALKING_ONE, i*sizeof(T)); return; } } } template static void walking_one(memtest_t *memp) { GeneratorWalkingOne generator; memtest_sequential(memp, generator, 1); } template static void walking_zero(memtest_t *memp) { GeneratorWalkingZero generator; memtest_sequential(memp, generator, 1); } template static void own_address(memtest_t *memp) { GeneratorOwnAddress generator; memtest_sequential(memp, generator, 0); } template static void moving_inversion_zero(memtest_t *memp) { GeneratorMovingInv generator; T mask = -1; memtest_sequential(memp, generator, 0); memtest_sequential(memp, generator, 0xFFFFFFFF & mask); } template static void moving_inversion_55aa(memtest_t *memp) { GeneratorMovingInv generator; T mask = -1; memtest_sequential(memp, generator, 0x55555555 & mask); memtest_sequential(memp, generator, 0xAAAAAAAA & mask); } template static void moving_inversion_rand(memtest_t *memp) { GeneratorMovingInvRand generator; T mask = -1; memtest_sequential(memp, generator, memp->rand_seed & mask); } /* * */ static void memtest_wrapper(memtest_t *memp, void (*p_u8)(memtest_t *memp), void (*p_u16)(memtest_t *memp), void (*p_u32)(memtest_t *memp)) { switch(memp->width){ case MEMTEST_WIDTH_32: p_u8(memp); p_u16(memp); p_u32(memp); break; case MEMTEST_WIDTH_16: p_u8(memp); p_u16(memp); break; case MEMTEST_WIDTH_8: p_u8(memp); break; } } /* * */ void memtest_run(memtest_t *memp, uint32_t testmask) { if ((testmask & MEMTEST_WALKING_ONE) == MEMTEST_WALKING_ONE) { memtest_wrapper(memp, walking_one, walking_one, walking_one); } if ((testmask & MEMTEST_WALKING_ZERO) == MEMTEST_WALKING_ZERO) { memtest_wrapper(memp, walking_zero, walking_zero, walking_zero); } if ((testmask & MEMTEST_OWN_ADDRESS) == MEMTEST_OWN_ADDRESS) { memtest_wrapper(memp, own_address, own_address, own_address); } if ((testmask & MEMTEST_MOVING_INVERSION_ZERO) == MEMTEST_MOVING_INVERSION_ZERO) { memtest_wrapper(memp, moving_inversion_zero, moving_inversion_zero, moving_inversion_zero); } if ((testmask & MEMTEST_MOVING_INVERSION_55AA) == MEMTEST_MOVING_INVERSION_55AA) { memtest_wrapper(memp, moving_inversion_55aa, moving_inversion_55aa, moving_inversion_55aa); } if ((testmask & MEMTEST_MOVING_INVERSION_RAND) == MEMTEST_MOVING_INVERSION_RAND) { memtest_wrapper(memp, moving_inversion_rand, moving_inversion_rand, moving_inversion_rand); } }