Commit 9b9479c9 authored by Thanassis Tsiodras's avatar Thanassis Tsiodras

Added comments about memory checking strategies.

parent 74e059f4
Pipeline #1210 skipped
......@@ -6,8 +6,9 @@
void memcheck()
{
#define MEMCHECK
#ifdef MEMCHECK
// Use alternating bit values to verify proper memory operations,
// by writing values in memory that stress (electrically) the circuits
uint32_t patterns[] = {
0x0,
0xFFFFFFFF,
......@@ -16,12 +17,19 @@ void memcheck()
0xAA55AA55,
0x55AA55AA,
};
// Prime numbers used to check for potential address space overlaps
// (read comments in the code below that uses this)
unsigned primes[] = { 3, 7, 31, 127 };
size_t space = 512*1024; // Allocated test memory space starts at 512K
void *p = malloc(space);
// Counters used in loops below.
int i = 0;
unsigned cnt = 0;
// Detect available memory by repeated allocations.
// Start at 512K.
size_t space = 512*1024;
void *p = malloc(space);
printf("[MEMCHECK] Detecting memory available");
while(p) {
free(p);
......@@ -33,6 +41,7 @@ void memcheck()
space -= 1024*1024;
printf("\n[MEMCHECK] Memory available: %dK\n", space/1024);
// Now that we know the amount of memory available, reserve it all.
p = malloc(space);
if (!p) {
puts("[MEMCHECK] Unexpected heap error. Aborting...");
......@@ -40,7 +49,31 @@ void memcheck()
exit(1);
}
// Check potential address space overlaps
// How can we make sure that RTEMS doesn't mis-identify our available
// memory and doesn't return 'windowed' areas? (i.e. we think we have
// e.g. 128KB, but in fact, the last 64KB 'mirror' back to the first
// 64KB)?
//
// Simple: we write sequences of values up to prime numbers - e.g.
//
// 0 1 2 0 1 2 0 1 ...
//
// If there is a wrap-around at some offset, the value written will
// NOT be the same as the first time we wrote at the 'mirror' offset,
// since any wraparounds will happen at power-of-two boundaries.
//
// e.g. for a mis-identified 8-byte area as a 16-byte one, we write...
//
// Offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// Values written: 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0
// ^
// `----- Here memory wraps-around
// Values read: 2 0 1 2 0 1 2 0
//
// Due to the use of a prime number, the wrap-around will be detected;
// we wrote a 0 at offset 0, but it was overwritten with a 2 when we
// wrote at offset 8 (which wrapped around - 'ghost' address space).
printf("[MEMCHECK] Checking for potential address space overlap. Window: ");
for (i=0; i<sizeof(primes)/sizeof(primes[0]); i++) {
uint8_t *pc = p;
......@@ -61,7 +94,8 @@ void memcheck()
cnt = 0;
while (bytes--) {
if (*pc != cnt) {
printf("[MEMCHECK] Address space wrapped around at 0x%x!\n", (unsigned)pc);
printf("[MEMCHECK] Address space wrapped around at 0x%x!\n",
(unsigned)pc);
fflush(stdout);
exit(1);
}
......@@ -74,8 +108,11 @@ void memcheck()
}
puts("");
// Write all over the memory using alternating bit values; this verifies
// proper memory operations, by stressing (electrically) the circuits.
for(i=0; i<sizeof(patterns)/sizeof(patterns[0]); i++) {
printf("[MEMCHECK] Checking memory with pattern: 0x%08x...\n", (unsigned) patterns[i]);
printf("[MEMCHECK] Checking memory with pattern: 0x%08x...\n",
(unsigned) patterns[i]);
uint32_t *pw = p;
unsigned words = space/4;
// Writing the pattern
......@@ -97,7 +134,7 @@ void memcheck()
}
}
// A final run storing big numbers.
// A simple final run storing big numbers consecutively.
printf("[MEMCHECK] Checking memory by writing 32-bit numbers from 0 up to %d...\n", space/4);
{
uint32_t *pw = p;
......@@ -122,7 +159,7 @@ void memcheck()
free(p);
#else
puts("[MEMCHECK] Memory checks disabled in release mode.");
puts("[MEMCHECK] Memory checks are disabled. Proceeding with main execution...");
fflush(stdout);
#endif
}
// Comment this to skip memory checks at startup
#define MEMCHECK
#include <rtems/score/types.h>
#include <rtems/rtems/types.h>
#include <rtems/rtems/tasks.h>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment