Advertisement
prefixcactus

smokers_memtest

Feb 11th, 2021 (edited)
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.72 KB | None | 0 0
  1. //this is placed at the end of board.c (as there's no way that I know of to cancel #pragma GCC optimize after it's applied)
  2.  
  3. #define ONEMEG ((1<<20)/sizeof(u32))
  4. #define MAXERRORS 50
  5.  
  6. #ifdef SMOKEMEM
  7. //HERE BE DRAGONS. No compiler optimization beyond this point!
  8. #pragma GCC optimize "O0"
  9.  
  10. //this memtest writes a fixed value to memory and reads it back in 1M blocks.
  11. static void smokers_memtest(u32 pattern)
  12. {
  13.   printf("smokers_memtest started, pattern %08x\n", pattern);
  14.   const u8* init_addr = (u8*) 0x40000000;
  15.   u32 errorcount=0;
  16.   u32* addr;
  17.   for(uint megs = 0; megs < 1024; megs++)
  18.   {
  19.     u32* baseaddr = (u32*)init_addr+ONEMEG*megs;
  20.     if(!(megs % 128)) {
  21.       printf("\n%d M || 0x%x\n", megs, baseaddr);
  22.     }
  23.     printf("."); //writing block
  24.     for(u32 offset = 0; offset < ONEMEG; ++offset)
  25.     {
  26.       *((volatile uint32_t *)baseaddr + offset) = pattern;
  27.     }
  28.     printf("'"); //reading block
  29.     for(u32 offset = 0; offset < ONEMEG; ++offset)
  30.     {
  31.       if (readl((u32*)baseaddr + offset) != pattern) {
  32.         if(++errorcount < MAXERRORS)
  33.           printf("\nerror @ %x: %x\n", (u32)addr, readl(addr));
  34.         //break;
  35.       }
  36.     }
  37.   }
  38.   printf("\n%d errors in pattern %08x\n",errorcount, pattern);
  39.   errorcount=0;
  40.   printf("smokers_memtest finished\n");
  41. };
  42.  
  43. //this memtest overwrites the whole DRAM with values of magic^addr, and then reads the whole DRAM back.
  44. static void magic_memtest(u32 magicval){
  45.   printf("\n magic_memtest started, magic value: %08x\n", magicval);
  46.   const u8* init_addr = (u8*) 0x40000000;
  47.   const unsigned meg_shift = 3; //8M steps
  48.   u32 errorcount=0;
  49.   u32* addr;
  50.   printf("writing...");
  51.   for(uint megs = 0; megs < 1024; megs+=1<<meg_shift)
  52.   {
  53.     u32* baseaddr = (u32*)init_addr+ONEMEG*megs;
  54.     if(!(megs % 128)) printf("\n%d M || 0x%x\n", megs, baseaddr);
  55.  
  56.     for(u32 offset = 0; offset < ONEMEG<<meg_shift; ++offset)
  57.     {
  58.       addr = (u32*)baseaddr+offset;
  59.       *((volatile uint32_t *)baseaddr + offset) = magicval^(u32)addr;
  60.     }
  61.     printf(".");
  62.   }
  63.   printf("\nreading...");
  64.   for(uint megs = 0; megs < 1024; megs+=1<<meg_shift)
  65.   {
  66.     u32* baseaddr = (u32*)init_addr+ONEMEG*megs;
  67.     if(!(megs % 128)) printf("\n%d M || 0x%x\n", megs, baseaddr);
  68.  
  69.     for(u32 offset = 0; offset < ONEMEG<<meg_shift; ++offset)
  70.     {
  71.       addr = (u32*)baseaddr+offset;
  72.       if ((u32)readl(addr) != (magicval^((u32)addr))) {
  73.         if(++errorcount < MAXERRORS)
  74.           printf("\nerror @ %08x: expected %08x, got %08x\n", (u32)addr, magicval^((u32)addr), (u32)readl(addr));
  75.         //break;
  76.       }
  77.     }
  78.     printf("'");
  79.   }
  80.  
  81.   printf("\n\n%d errors for magic %08x\n",errorcount, magicval);
  82.   printf("magic_memtest finished\n");
  83. }
  84. #endif //SMOKEMEM
  85.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement