Logo Search packages:      
Sourcecode: qi version File versions  Download package

memory-test.c

#include <qi.h>
#include <string.h>

int memory_test_const32(void * start, unsigned int length, u32 value)
{
      int errors = 0;
      u32 * p = (u32 *)start;
      u32 * pend = (u32 *)(start + length);
      int count = length >> 2;

      puts(".");

      while (p < pend)
            *p++ = value;

      p = (u32 *)start;
      count = length >> 2;

      while (count--)
            if (*p++ != value) {
                  puts("*** Error ");
                  print32((long)p - 4);
                  errors++;
            }

      return errors;
}

int memory_test_ads(void * start, unsigned int length, u32 mask)
{
      int errors = 0;
      u32 * p = (u32 *)start;
      u32 * pend = (u32 *)(start + length);

      puts(".");

      while (p < pend)
            if ((u32)p & mask)
                  *p++ = 0xffffffff;
            else
                  *p++ = 0;

      p = (u32 *)start;

      while (p < pend) {
            if ((u32)p & mask) {
                  if (*p++ != 0xffffffff) {
                        puts("*** Error ");
                        print32((long)p - 4);
                        errors++;
                  }
            } else {
                  if (*p++) {
                        puts("*** Error ");
                        print32((long)p - 4);
                        errors++;
                  }
            }
      }
      return errors;
}

int memory_test_walking1(void * start, unsigned int length)
{
      int errors = 0;
      u32 value = 1;

      while (value) {
            errors += memory_test_const32(start, length, value);
            value <<= 1;
      }

      return errors;
}

/* negative runs == run forever */

void __memory_test(void * start, unsigned int length)
{
      int errors = 0;
      int series = 0;
      int mask;

      puts("\nMemory Testing 0x");
      print32((u32)start);
      puts(" length ");
      printdec(length >> 20);
      puts(" MB\n");

      while (1) {
            puts(" Test series ");
            printdec(series + 1);
            puts("  ");

            /* these are looking at data issues, they flood the whole
             * array with the same data
             */

            errors += memory_test_const32(start, length, 0x55555555);
            errors += memory_test_const32(start, length, 0xaaaaaaaa);
            errors += memory_test_const32(start, length, 0x55aa55aa);
            errors += memory_test_const32(start, length, 0xaa55aa55);
            errors += memory_test_const32(start, length, 0x00ff00ff);
            errors += memory_test_const32(start, length, 0xff00ff00);
            errors += memory_test_walking1(start, length);

            /* this is looking at addressing issues, it floods only
             * addresses meeting a walking mask with 0xffffffff (the rest
             * is zeroed), and makes sure all the bits are only seen where
             * they were placed
             */

            mask = 1;
            while (! (length & mask)) {
                  errors += memory_test_ads(start, length, mask);
                  mask = mask << 1;
            }

            puts("  Total errors: ");
            printdec(errors);
            puts("\n");

            series++;
      }
}


void memory_test(void * start, unsigned int length)
{
      /* it's a small steppingstone stack from start.S */
      extern int _ss_stack;

      /*
       * we won't be coming back from this, so just force our local stack to
       * steppingstone out of the way of main memory test action
       *
       * then jump into the actual test
       */
      asm volatile (
            "mov  sp, %0\n"
            : : "r" (&_ss_stack)
      );

      __memory_test(start, length);
}

Generated by  Doxygen 1.6.0   Back to index