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 @@ ...@@ -6,8 +6,9 @@
void memcheck() void memcheck()
{ {
#define MEMCHECK
#ifdef 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[] = { uint32_t patterns[] = {
0x0, 0x0,
0xFFFFFFFF, 0xFFFFFFFF,
...@@ -16,12 +17,19 @@ void memcheck() ...@@ -16,12 +17,19 @@ void memcheck()
0xAA55AA55, 0xAA55AA55,
0x55AA55AA, 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 }; 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; int i = 0;
unsigned cnt = 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"); printf("[MEMCHECK] Detecting memory available");
while(p) { while(p) {
free(p); free(p);
...@@ -33,6 +41,7 @@ void memcheck() ...@@ -33,6 +41,7 @@ void memcheck()
space -= 1024*1024; space -= 1024*1024;
printf("\n[MEMCHECK] Memory available: %dK\n", space/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); p = malloc(space);
if (!p) { if (!p) {
puts("[MEMCHECK] Unexpected heap error. Aborting..."); puts("[MEMCHECK] Unexpected heap error. Aborting...");
...@@ -40,7 +49,31 @@ void memcheck() ...@@ -40,7 +49,31 @@ void memcheck()
exit(1); 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: "); printf("[MEMCHECK] Checking for potential address space overlap. Window: ");
for (i=0; i<sizeof(primes)/sizeof(primes[0]); i++) { for (i=0; i<sizeof(primes)/sizeof(primes[0]); i++) {
uint8_t *pc = p; uint8_t *pc = p;
...@@ -61,7 +94,8 @@ void memcheck() ...@@ -61,7 +94,8 @@ void memcheck()
cnt = 0; cnt = 0;
while (bytes--) { while (bytes--) {
if (*pc != cnt) { 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); fflush(stdout);
exit(1); exit(1);
} }
...@@ -74,8 +108,11 @@ void memcheck() ...@@ -74,8 +108,11 @@ void memcheck()
} }
puts(""); 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++) { 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; uint32_t *pw = p;
unsigned words = space/4; unsigned words = space/4;
// Writing the pattern // Writing the pattern
...@@ -97,7 +134,7 @@ void memcheck() ...@@ -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); printf("[MEMCHECK] Checking memory by writing 32-bit numbers from 0 up to %d...\n", space/4);
{ {
uint32_t *pw = p; uint32_t *pw = p;
...@@ -122,7 +159,7 @@ void memcheck() ...@@ -122,7 +159,7 @@ void memcheck()
free(p); free(p);
#else #else
puts("[MEMCHECK] Memory checks disabled in release mode."); puts("[MEMCHECK] Memory checks are disabled. Proceeding with main execution...");
fflush(stdout); fflush(stdout);
#endif #endif
} }
// Comment this to skip memory checks at startup
#define MEMCHECK
#include <rtems/score/types.h> #include <rtems/score/types.h>
#include <rtems/rtems/types.h> #include <rtems/rtems/types.h>
#include <rtems/rtems/tasks.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