memtester support in kernel

This commit is contained in:
yangkai
2011-03-23 19:22:35 +08:00
parent 3ea1f96dc7
commit 1497220f4f
7 changed files with 974 additions and 12 deletions

View File

@@ -1,4 +1,5 @@
obj-y += timer.o io.o devices.o iomux.o clock.o rk29-pl330.o dma.o gpio.o ddr.o sram.o memcpy_dma.o reset.o
obj-y += tests.o memtester.o
obj-y += early_printk.o
ifndef CONFIG_DEBUG_LL
obj-y += ../kernel/debug.o

View File

@@ -34,7 +34,7 @@
#include <asm/io.h>
#define ddr_print(x...) printk( "ddr init: " x )
#define ddr_print(x...) printk( "DDR DEBUG: " x )
// save_sp must be static global variable
@@ -1006,7 +1006,7 @@ refresh:
pDDR_Reg->CCR |= HOSTEN; //enable host port
}
void __sramfunc ddr_change_freq(uint32_t nMHz)
uint32_t __sramfunc ddr_change_freq(uint32_t nMHz)
{
uint32_t ret;
volatile u32 n;
@@ -1057,6 +1057,7 @@ void __sramfunc ddr_change_freq(uint32_t nMHz)
DDR_RESTORE_SP(save_sp);
local_irq_restore(flags);
return ret;
//ddr_print("%s exit\n", __func__);
}
void __sramfunc ddr_suspend(void)
@@ -1213,7 +1214,7 @@ static int __init ddr_probe(void)
if((mem_type == DDRII) || (mem_type == DDR3))
{
pDDR_Reg->ALPMR = LPPERIOD_POWER_DOWN(0xFF);// | AUTOPD;
pDDR_Reg->ALPMR = LPPERIOD_POWER_DOWN(0xFF) | AUTOPD;
}
else
{
@@ -1226,9 +1227,8 @@ static int __init ddr_probe(void)
Hz = clk_get_rate(clk_get(NULL,"ddr"));
MHz = Hz/1000000;
ddr_change_freq(MHz);
ddr_print("ddr pll freq=%dMHz\n", MHz);
return 0;
value = ddr_change_freq(MHz);
ddr_print("init success!!! freq=%dMHz\n", value);
return 0;
}
core_initcall_sync(ddr_probe);

View File

@@ -0,0 +1,19 @@
/*
* Very simple (yet, for some reason, very effective) memory tester.
* Originally by Simon Kirby <sim@stormix.com> <sim@neato.org>
* Version 2 by Charles Cazabon <charlesc-memtester@pyropus.ca>
* Version 3 not publicly released.
* Version 4 rewrite:
* Copyright (C) 2007-2009 Charles Cazabon <charlesc-memtester@pyropus.ca>
* Licensed under the terms of the GNU General Public License version 2 (only).
* See the file COPYING for details.
*
* This file contains the declarations for external variables from the main file.
* See other comments in that file.
*
*/
/* extern declarations. */
extern void memtester(void);

177
arch/arm/mach-rk29/memtester.c Executable file
View File

@@ -0,0 +1,177 @@
/*
* memtester version 4
*
* Very simple but very effective user-space memory tester.
* Originally by Simon Kirby <sim@stormix.com> <sim@neato.org>
* Version 2 by Charles Cazabon <charlesc-memtester@pyropus.ca>
* Version 3 not publicly released.
* Version 4 rewrite:
* Copyright (C) 2007-2009 Charles Cazabon <charlesc-memtester@pyropus.ca>
* Licensed under the terms of the GNU General Public License version 2 (only).
* See the file COPYING for details.
*
*/
#include <linux/kernel.h>
#include <linux/slab.h>
#include "tests.h"
#define EXIT_FAIL_NONSTARTER 0x01
#define EXIT_FAIL_ADDRESSLINES 0x02
#define EXIT_FAIL_OTHERTEST 0x04
//#pragma arm section rwdata="DDR"
useful_data_t useful_data={(2*1024*1024), 133, 333};
//#pragma arm section
struct test tests[17]
= {
#ifdef TEST_RANDOM
{ "Random Value", test_random_value },
#endif
#ifdef TEST_XOR
{ "Compare XOR", test_xor_comparison },
#endif
#ifdef TEST_SUB
{ "Compare SUB", test_sub_comparison },
#endif
#ifdef TEST_MUL
{ "Compare MUL", test_mul_comparison },
#endif
#ifdef TEST_DIV
{ "Compare DIV",test_div_comparison },
#endif
#ifdef TEST_OR
{ "Compare OR", test_or_comparison },
#endif
#ifdef TEST_AND
{ "Compare AND", test_and_comparison },
#endif
#ifdef TEST_SEQINC
{ "Sequential Increment", test_seqinc_comparison },
#endif
#ifdef TEST_SOLID_BIT
{ "Solid Bits", test_solidbits_comparison },
#endif
#ifdef TEST_BLOCK_SEQ
{ "Block Sequential", test_blockseq_comparison },
#endif
#ifdef TEST_CHECK_BOARD
{ "Checkerboard", test_checkerboard_comparison },
#endif
#ifdef TEST_BIT_SPREAD
{ "Bit Spread", test_bitspread_comparison },
#endif
#ifdef TEST_BIT_FLIP
{ "Bit Flip", test_bitflip_comparison },
#endif
#ifdef TEST_ONE
{ "Walking Ones", test_walkbits1_comparison },
#endif
#ifdef TEST_ZERO
{ "Walking Zeroes", test_walkbits0_comparison },
#endif
{ NULL, NULL }
};
int exit_code = 0;
int memtester(void) {
ul loops, loop, i;
size_t pagesize, wantraw, wantmb, wantbytes, wantbytes_orig, bufsize,
halflen, count;
ptrdiff_t pagesizemask;
void volatile *buf, *aligned;
ulv *bufa, *bufb;
int memshift;
ul cap;
print("Copyright (C) 2009 Charles Cazabon.\n");
print("Licensed under the GNU General Public License version 2 (only).\n");
print("\n");
pagesize = 1024;
pagesizemask = (ptrdiff_t) ~(pagesize - 1);
print("pagesizemask is 0x");
print_Hex(pagesizemask);
print("\n");
if(useful_data.testCap == 0xFFFFFFFF)
{
cap = 0x800000 << (((pDDR_Reg->DCR >> 4) & 0x7)
+ ((((pDDR_Reg->DCR >> 7) & 0x7)+1) >> ((pDDR_Reg->DCR >> 2) & 0x3))
+ ((pDDR_Reg->DCR >> 11) & 0x3));
}
else if(useful_data.testCap == 0)
{
cap = (0x1 << 20);
}
else
{
cap = useful_data.testCap;
}
wantraw = cap>>20;
memshift = 20; /* megabytes */
wantbytes_orig = wantbytes = ((size_t) wantraw << memshift);
wantmb = (wantbytes_orig >> 20);
loops = 10;
print("want ");
print_Dec((ull) wantmb);
print("MB (");
print_Dec((ull) wantbytes);
print(" bytes)\n");
buf = NULL;
buf = (void volatile *) kmalloc(wantbytes, GFP_KERNEL);
// buf = (void volatile *)0x60000000;
bufsize = wantbytes;
aligned = buf;
halflen = bufsize / 2;
count = halflen / sizeof(ul);
bufa = (ulv *) aligned;
bufb = (ulv *) ((size_t) aligned + halflen);
for(loop=1; ((!loops) || loop <= loops); loop++) {
print("Loop ");
print_Dec(loop);
//if (loops) {
// print_Dec(loops);
//}
print(":\n");
print(" Stuck Address: ");
if (!test_stuck_address(aligned, bufsize / sizeof(ul))) {
print("ok\n");
} else {
exit_code |= EXIT_FAIL_ADDRESSLINES;
goto error;
}
for (i=0;;i++) {
if (!tests[i].name) break;
print(" ");
print(tests[i].name);
print(": ");
if (!tests[i].fp(bufa, bufb, count)) {
print("ok\n");
} else {
exit_code |= EXIT_FAIL_OTHERTEST;
goto error;
}
}
print("\n");
}
kfree((const void *)buf);
print("Done.\n");
return 0;
error:
print("failed\n");
return 1;
}

View File

@@ -25,6 +25,7 @@
#include <mach/sram.h>
#include <mach/gpio.h>
#include <mach/ddr.h>
#include <mach/memtester.h>
#define cru_readl(offset) readl(RK29_CRU_BASE + offset)
#define cru_writel(v, offset) do { writel(v, RK29_CRU_BASE + offset); readl(RK29_CRU_BASE + offset); } while (0)
@@ -71,13 +72,59 @@ static void/* inline*/ __sramfunc printch(char byte)
printch('\r');
}
static void inline printascii(const char *s)
static void __sramfunc printascii(const char *s)
{
while (*s) {
printch(*s);
s++;
if (*s == '\n')
{
printch('\r');
}
printch(*s);
s++;
}
}
void print(const char *s)
{
printascii(s);
}
void __sramfunc print_Hex(unsigned int hex)
{
int i = 8;
printch('0');
printch('x');
while (i--) {
unsigned char c = (hex & 0xF0000000) >> 28;
printch(c < 0xa ? c + '0' : c - 0xa + 'a');
hex <<= 4;
}
}
void __sramfunc print_Dec (uint32_t n)
{
if (n >= 10)
{
print_Dec(n / 10);
n %= 10;
}
printch((char)(n + '0'));
}
void print_Dec_3(uint32_t value)
{
if(value<10)
{
print(" ");
}
else if(value<100)
{
print(" ");
}
else
{
}
print_Dec(value);
}
static void /* inline*/ __sramfunc printhex(unsigned int hex)
{
@@ -209,7 +256,10 @@ void __sramfunc ddr_testmode(void)
// printascii("self refresh success\n");
}
}
else if(ddr_debug == 3)
{
memtester();
}
}
#else
void __sramfunc ddr_testmode(void)
@@ -220,7 +270,7 @@ static void __sramfunc rk29_sram_suspend(void)
{
u32 clksel0;
if(ddr_debug)
if((ddr_debug == 1)||(ddr_debug == 2))
ddr_testmode();
printch('5');
ddr_suspend();
@@ -285,6 +335,11 @@ static int rk29_pm_enter(suspend_state_t state)
{
u32 apll, cpll, gpll, mode, clksel0;
u32 clkgate[4];
// memory teseter
if(ddr_debug == 3)
ddr_testmode();
printch('0');
#ifdef CONFIG_RK29_PWM_REGULATOR

515
arch/arm/mach-rk29/tests.c Executable file
View File

@@ -0,0 +1,515 @@
/*
* Very simple but very effective user-space memory tester.
* Originally by Simon Kirby <sim@stormix.com> <sim@neato.org>
* Version 2 by Charles Cazabon <charlesc-memtester@pyropus.ca>
* Version 3 not publicly released.
* Version 4 rewrite:
* Copyright (C) 2007-2009 Charles Cazabon <charlesc-memtester@pyropus.ca>
* Licensed under the terms of the GNU General Public License version 2 (only).
* See the file COPYING for details.
*
* This file contains the functions for the actual tests, called from the
* main routine in memtester.c. See other comments in that file.
*
*/
#include "tests.h"
char progress[] = "-\\|/";
#define PROGRESSLEN 4
#define PROGRESSOFTEN 2500
int compare_regions(ulv *bufa, ulv *bufb, size_t count) {
int r = 0;
size_t i;
ulv *p1 = bufa;
ulv *p2 = bufb;
int n=0;
for (i = 0; i < count; i++, p1++, p2++) {
if (*p1 != *p2) {
{
print("FAILURE: 0x");
print_Hex((ul) *p1);
print(" != 0x");
print_Hex((ul) *p2);
print(" at offset 0x");
print_Hex((ul) i);
print(".\n");
}
/* printf("Skipping to next test..."); */
r = -1;
n++;
if(n>10)
{
break;
}
}
}
return r;
}
int compare_regions_reverse(ulv *bufa, ulv *bufb, size_t count) {
int r = 0;
size_t i;
ulv *p1 = bufa;
ulv *p2 = bufb;
int n=0;
for (i = 0; i < count; i++, p1++, p2++) {
if (*p1 != ~(*p2)) {
{
print("FAILURE: 0x");
print_Hex((ul) *p1);
print(" != 0x");
print_Hex((ul) *p2);
print(" at offset 0x");
print_Hex((ul) i);
print(".\n");
}
/* printf("Skipping to next test..."); */
r = -1;
n++;
if(n>10)
{
break;
}
}
}
return r;
}
int test_stuck_address(ulv *bufa, size_t count) {
ulv *p1 = bufa;
unsigned int j;
size_t i;
print(" ");
for (j = 0; j < 16; j++) {
print("\b\b\b\b\b\b\b\b\b\b\b");
p1 = (ulv *) bufa;
print("setting ");
print_Dec_3(j);
for (i = 0; i < count; i++) {
*p1 = ((j + i) % 2) == 0 ? (ul) p1 : ~((ul) p1);
*p1++;
}
print("\b\b\b\b\b\b\b\b\b\b\b");
print("testing ");
print_Dec_3(j);
p1 = (ulv *) bufa;
for (i = 0; i < count; i++, p1++) {
if (*p1 != (((j + i) % 2) == 0 ? (ul) p1 : ~((ul) p1))) {
{
print("FAILURE: possible bad address line at offset 0x");
print_Hex((ul) i);
print(".\n");
}
print("Skipping to next test...\n");
return -1;
}
}
}
print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
return 0;
}
#ifdef TEST_RANDOM
int test_random_value(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
size_t i;
for (i = 0; i < count; i++) {
*p1++ = *p2++ = rand_ul();
if (!(i % PROGRESSOFTEN)) {
}
}
print("\b \b");
return compare_regions(bufa, bufb, count);
}
#endif
#ifdef TEST_XOR
int test_xor_comparison(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
size_t i;
ul q = rand_ul();
for (i = 0; i < count; i++) {
*p1++ ^= q;
*p2++ ^= q;
}
return compare_regions(bufa, bufb, count);
}
#endif
#ifdef TEST_SUB
int test_sub_comparison(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
size_t i;
ul q = rand_ul();
for (i = 0; i < count; i++) {
*p1++ -= q;
*p2++ -= q;
}
return compare_regions(bufa, bufb, count);
}
#endif
#ifdef TEST_MUL
int test_mul_comparison(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
size_t i;
ul q = rand_ul();
for (i = 0; i < count; i++) {
*p1++ *= q;
*p2++ *= q;
}
return compare_regions(bufa, bufb, count);
}
#endif
#ifdef TEST_DIV
int test_div_comparison(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
size_t i;
ul q = rand_ul();
for (i = 0; i < count; i++) {
if (!q) {
q++;
}
*p1++ /= q;
*p2++ /= q;
}
return compare_regions(bufa, bufb, count);
}
#endif
#ifdef TEST_OR
int test_or_comparison(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
size_t i;
ul q = rand_ul();
for (i = 0; i < count; i++) {
*p1++ |= q;
*p2++ |= q;
}
return compare_regions(bufa, bufb, count);
}
#endif
#ifdef TEST_AND
int test_and_comparison(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
size_t i;
ul q = rand_ul();
for (i = 0; i < count; i++) {
*p1++ &= q;
*p2++ &= q;
}
return compare_regions(bufa, bufb, count);
}
#endif
#ifdef TEST_SEQINC
int test_seqinc_comparison(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
size_t i;
ul q = rand_ul();
ul value;
for (i = 0; i < count; i++) {
value = (i+q);
*p1++ = value;
*p2++ = ~value;
//*p1++ = *p2++ = (i + q);
}
return compare_regions_reverse(bufa, bufb, count);
}
#endif
#ifdef TEST_SOLID_BIT
int test_solidbits_comparison(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
unsigned int j;
ul q;
size_t i;
ul value;
print(" ");
for (j = 0; j < 64; j++) {
print("\b\b\b\b\b\b\b\b\b\b\b");
q = (j % 2) == 0 ? UL_ONEBITS : 0;
print("setting ");
print_Dec_3(j);
p1 = (ulv *) bufa;
p2 = (ulv *) bufb;
for (i = 0; i < count; i++) {
value = (i % 2) == 0 ? q : ~q;
*p1++ = value;
*p2++ = ~value;
//*p1++ = *p2++ = (i % 2) == 0 ? q : ~q;
}
print("\b\b\b\b\b\b\b\b\b\b\b");
print("testing ");
print_Dec_3(j);
if (compare_regions_reverse(bufa, bufb, count)) {
return -1;
}
}
print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
return 0;
}
#endif
#ifdef TEST_CHECK_BOARD
int test_checkerboard_comparison(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
unsigned int j;
ul q;
size_t i;
ul value;
print(" ");
for (j = 0; j < 64; j++) {
print("\b\b\b\b\b\b\b\b\b\b\b");
q = (j % 2) == 0 ? CHECKERBOARD1 : CHECKERBOARD2;
print("setting ");
print_Dec_3(j);
p1 = (ulv *) bufa;
p2 = (ulv *) bufb;
for (i = 0; i < count; i++) {
value = (i % 2) == 0 ? q : ~q;
*p1++ = value;
*p2++ = ~value;
//*p1++ = *p2++ = (i % 2) == 0 ? q : ~q;
}
print("\b\b\b\b\b\b\b\b\b\b\b");
print("testing ");
print_Dec_3(j);
if (compare_regions_reverse(bufa, bufb, count)) {
return -1;
}
}
print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
return 0;
}
#endif
#ifdef TEST_BLOCK_SEQ
int test_blockseq_comparison(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
unsigned int j;
size_t i;
ul value;
print(" ");
for (j = 0; j < 256; j++) {
print("\b\b\b\b\b\b\b\b\b\b\b");
p1 = (ulv *) bufa;
p2 = (ulv *) bufb;
print("setting ");
print_Dec_3(j);
for (i = 0; i < count; i++) {
value = (ul) UL_BYTE(j);
*p1++ = value;
*p2++ = ~value;
//*p1++ = *p2++ = (ul) UL_BYTE(j);
}
print("\b\b\b\b\b\b\b\b\b\b\b");
print("testing ");
print_Dec_3(j);
if (compare_regions_reverse(bufa, bufb, count)) {
return -1;
}
}
print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
return 0;
}
#endif
#ifdef TEST_ZERO
int test_walkbits0_comparison(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
unsigned int j;
size_t i;
ul value;
print(" ");
for (j = 0; j < UL_LEN * 2; j++) {
print("\b\b\b\b\b\b\b\b\b\b\b");
p1 = (ulv *) bufa;
p2 = (ulv *) bufb;
print("setting ");
print_Dec_3(j);
for (i = 0; i < count; i++) {
if (j < UL_LEN) { /* Walk it up. */
//*p1++ = *p2++ = 0x00000001 << j;
value = 0x00000001 << j;
*p1++ = value;
*p2++ = ~value;
} else { /* Walk it back down. */
//*p1++ = *p2++ = 0x00000001 << (UL_LEN * 2 - j - 1);
value = 0x00000001 << (UL_LEN * 2 - j - 1);
*p1++ = value;
*p2++ = ~value;
}
}
print("\b\b\b\b\b\b\b\b\b\b\b");
print("testing ");
print_Dec_3(j);
if (compare_regions_reverse(bufa, bufb, count)) {
return -1;
}
}
print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
return 0;
}
#endif
#ifdef TEST_ONE
int test_walkbits1_comparison(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
unsigned int j;
size_t i;
ul value;
print(" ");
for (j = 0; j < UL_LEN * 2; j++) {
print("\b\b\b\b\b\b\b\b\b\b\b");
p1 = (ulv *) bufa;
p2 = (ulv *) bufb;
print("setting ");
print_Dec_3(j);
for (i = 0; i < count; i++) {
if (j < UL_LEN) { /* Walk it up. */
//*p1++ = *p2++ = UL_ONEBITS ^ (0x00000001 << j);
value = UL_ONEBITS ^ (0x00000001 << j);
*p1++ = value;
*p2++ = ~value;
} else { /* Walk it back down. */
//*p1++ = *p2++ = UL_ONEBITS ^ (0x00000001 << (UL_LEN * 2 - j - 1));
value = UL_ONEBITS ^ (0x00000001 << (UL_LEN * 2 - j - 1));
*p1++ = value;
*p2++ = ~value;
}
}
print("\b\b\b\b\b\b\b\b\b\b\b");
print("testing ");
print_Dec_3(j);
if (compare_regions_reverse(bufa, bufb, count)) {
return -1;
}
}
print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
return 0;
}
#endif
#ifdef TEST_BIT_SPREAD
int test_bitspread_comparison(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
unsigned int j;
size_t i;
ul value;
print(" ");
for (j = 0; j < UL_LEN * 2; j++) {
print("\b\b\b\b\b\b\b\b\b\b\b");
p1 = (ulv *) bufa;
p2 = (ulv *) bufb;
print("setting ");
print_Dec_3(j);
for (i = 0; i < count; i++) {
if (j < UL_LEN) { /* Walk it up. */
//*p1++ = *p2++ = (i % 2 == 0)
// ? (0x00000001 << j) | (0x00000001 << (j + 2))
// : UL_ONEBITS ^ ((0x00000001 << j)
// | (0x00000001 << (j + 2)));
value = (i % 2 == 0)
? (0x00000001 << j) | (0x00000001 << (j + 2))
: UL_ONEBITS ^ ((0x00000001 << j)
| (0x00000001 << (j + 2)));
*p1++ = value;
*p2++ = ~value;
} else { /* Walk it back down. */
//*p1++ = *p2++ = (i % 2 == 0)
// ? (0x00000001 << (UL_LEN * 2 - 1 - j)) | (0x00000001 << (UL_LEN * 2 + 1 - j))
// : UL_ONEBITS ^ (0x00000001 << (UL_LEN * 2 - 1 - j)
// | (0x00000001 << (UL_LEN * 2 + 1 - j)));
value = (i % 2 == 0)
? (0x00000001 << (UL_LEN * 2 - 1 - j)) | (0x00000001 << (UL_LEN * 2 + 1 - j))
: UL_ONEBITS ^ (0x00000001 << (UL_LEN * 2 - 1 - j)
| (0x00000001 << (UL_LEN * 2 + 1 - j)));
*p1++ = value;
*p2++ = ~value;
}
}
print("\b\b\b\b\b\b\b\b\b\b\b");
print("testing ");
print_Dec_3(j);
if (compare_regions_reverse(bufa, bufb, count)) {
return -1;
}
}
print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
return 0;
}
#endif
#ifdef TEST_BIT_FLIP
int test_bitflip_comparison(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
ulv *p2 = bufb;
unsigned int j, k;
ul q;
size_t i;
ul value;
print(" ");
for (k = 0; k < UL_LEN; k++) {
q = 0x00000001 << k;
for (j = 0; j < 8; j++) {
print("\b\b\b\b\b\b\b\b\b\b\b");
q = ~q;
print("setting ");
print_Dec_3(k * 8 + j);
p1 = (ulv *) bufa;
p2 = (ulv *) bufb;
for (i = 0; i < count; i++) {
//*p1++ = *p2++ = (i % 2) == 0 ? q : ~q;
value = (i % 2) == 0 ? q : ~q;
*p1++ = value;
*p2++ = ~value;
}
print("\b\b\b\b\b\b\b\b\b\b\b");
print("testing ");
print_Dec_3(k * 8 + j);
if (compare_regions_reverse(bufa, bufb, count)) {
return -1;
}
}
}
print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
return 0;
}
#endif

195
arch/arm/mach-rk29/tests.h Executable file
View File

@@ -0,0 +1,195 @@
/*
* Very simple yet very effective memory tester.
* Originally by Simon Kirby <sim@stormix.com> <sim@neato.org>
* Version 2 by Charles Cazabon <charlesc-memtester@pyropus.ca>
* Version 3 not publicly released.
* Version 4 rewrite:
* Copyright (C) 2007-2009 Charles Cazabon <charlesc-memtester@pyropus.ca>
* Licensed under the terms of the GNU General Public License version 2 (only).
* See the file COPYING for details.
*
* This file contains the declarations for the functions for the actual tests,
* called from the main routine in memtester.c. See other comments in that
* file.
*
*/
#include <linux/kernel.h>
#include <mach/rk29_iomap.h>
#include <linux/random.h>
//#if (ULONG_MAX == 4294967295UL)
#if 1
#define rand_ul() random32()
#define UL_ONEBITS 0xffffffff
#define UL_LEN 32
#define CHECKERBOARD1 0x55555555
#define CHECKERBOARD2 0xaaaaaaaa
#define UL_BYTE(x) ((x | x << 8 | x << 16 | x << 24))
#elif (ULONG_MAX == 18446744073709551615ULL)
#define rand64() (((ul) rand32()) << 32 | ((ul) rand32()))
#define rand_ul() rand64()
#define UL_ONEBITS 0xffffffffffffffffUL
#define UL_LEN 64
#define CHECKERBOARD1 0x5555555555555555
#define CHECKERBOARD2 0xaaaaaaaaaaaaaaaa
#define UL_BYTE(x) (((ul)x | (ul)x<<8 | (ul)x<<16 | (ul)x<<24 | (ul)x<<32 | (ul)x<<40 | (ul)x<<48 | (ul)x<<56))
#else
#error long on this platform is not 32 or 64 bits
#endif
#define TEST_ALL
#ifdef TEST_ALL // TEST_ALL<4C><4C>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Щ<EFBFBD><D0A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define TEST_RANDOM
#define TEST_XOR
#define TEST_SUB
#define TEST_MUL
#define TEST_DIV
#define TEST_OR
#define TEST_AND
#define TEST_SEQINC
#define TEST_SOLID_BIT
#define TEST_BLOCK_SEQ
#define TEST_CHECK_BOARD
#define TEST_BIT_SPREAD
#define TEST_BIT_FLIP
#define TEST_ONE
#define TEST_ZERO
#else //<2F><>Щ<EFBFBD><D0A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ
//#define TEST_RANDOM
//#define TEST_XOR
//#define TEST_SUB
//#define TEST_MUL
//#define TEST_DIV
//#define TEST_OR
//#define TEST_AND
//#define TEST_SEQINC
//#define TEST_SOLID_BIT
//#define TEST_BLOCK_SEQ
//#define TEST_CHECK_BOARD
//#define TEST_BIT_SPREAD
#define TEST_BIT_FLIP
//#define TEST_ONE
//#define TEST_ZERO
#endif
typedef unsigned long ul;
typedef unsigned long long ull;
typedef unsigned long volatile ulv;
/* DDR Controller register struct */
typedef volatile struct DDR_REG_Tag
{
volatile unsigned int CCR; //Controller Configuration Register
volatile unsigned int DCR; //DRAM Configuration Register
volatile unsigned int IOCR; //IO Configuration Register
volatile unsigned int CSR; //Controller Status Register
volatile unsigned int DRR; //DRAM Refresh Register
volatile unsigned int TPR[3]; //SDRAM Timing Parameters Registers
volatile unsigned int DLLCR; //Global DLL Control Register
volatile unsigned int DLLCR09[10]; //DDR Control Register 0-9
volatile unsigned int RSLR[4]; //Rank System Latency Register 0-3
volatile unsigned int RDGR[4]; //Rank DQS Gating Register 0-3
volatile unsigned int DQTR[9]; //DQ Timing Register 0-8
volatile unsigned int DQSTR; //DQS Timing Register
volatile unsigned int DQSBTR; //DQS_b Timing Register
volatile unsigned int ODTCR; //ODT Configuration Register
volatile unsigned int DTR[2]; //Data Training Register 0-1
volatile unsigned int DTAR; //Data Training Address Register
volatile unsigned int ZQCR[3]; //SDRAM ZQ Control Register and SDRAM ZQCS Control Register 0-2
volatile unsigned int ZQSR; //SDRAM ZQ Status Register
volatile unsigned int TPR3; //SDRAM Timing Parameters Register 3
volatile unsigned int ALPMR; //Automatic Low Power Mode Register
volatile unsigned int Reserved[0x7c-0x30];
volatile unsigned int MR; //Mode Register
volatile unsigned int EMR; //Extended Mode Register
volatile unsigned int EMR2; //Extended Mode Register 2
volatile unsigned int EMR3; //Extended Mode Register 3
//Memory Management Unit Registers
volatile unsigned int HPCR[32]; //Host Port Configuration Register 0-31
volatile unsigned int PQCR[8]; //Priority Queue Configuration Register 0-7
volatile unsigned int MMGCR; //Memory Manager General Configuration Register
}DDR_REG_T, *pDDR_REG_T;
typedef struct tagGPIO_IOMUX
{
volatile unsigned int GPIOL_IOMUX;
volatile unsigned int GPIOH_IOMUX;
}GPIO_IOMUX_T;
//GRF Registers
typedef volatile struct tagREG_FILE
{
volatile unsigned int GRF_GPIO_DIR[6];
volatile unsigned int GRF_GPIO_DO[6];
volatile unsigned int GRF_GPIO_EN[6];
GPIO_IOMUX_T GRF_GPIO_IOMUX[6];
volatile unsigned int GRF_GPIO_PULL[7];
volatile unsigned int GRF_UOC_CON[2];
volatile unsigned int GRF_USB_CON;
volatile unsigned int GRF_CPU_CON[2];
volatile unsigned int GRF_CPU_STATUS;
volatile unsigned int GRF_MEM_CON;
volatile unsigned int GRF_MEM_STATUS[3];
volatile unsigned int GRF_SOC_CON[5];
volatile unsigned int GRF_OS_REG[4];
} REG_FILE, *pREG_FILE;
//CRU Registers
typedef volatile struct tagCRU_REG
{
volatile unsigned int CRU_APLL_CON;
volatile unsigned int CRU_DPLL_CON;
volatile unsigned int CRU_CPLL_CON;
volatile unsigned int CRU_PPLL_CON;
volatile unsigned int CRU_MODE_CON;
volatile unsigned int CRU_CLKSEL_CON[18];
volatile unsigned int CRU_CLKGATE_CON[4];
volatile unsigned int CRU_SOFTRST_CON[3];
} CRU_REG, *pCRU_REG;
#define pDDR_Reg ((pDDR_REG_T)RK29_DDRC_BASE)
#define pGRF_Reg ((pREG_FILE)RK29_GRF_BASE)
#define pSCU_Reg ((pCRU_REG)RK29_CRU_BASE)
struct test
{
char *name;
int (*fp)(ulv *bufa, ulv *bufb, size_t count);
};
typedef struct useful_data_tag
{
unsigned int testCap; //<2F><><EFBFBD>Ե<EFBFBD><D4B5><EFBFBD><EFBFBD><EFBFBD>
unsigned int WriteFreq;
unsigned int ReadFreq;
}useful_data_t;
extern void printascii(const char *s);
extern void print_Dec(unsigned int n);
extern void print_Hex(unsigned int hex);
extern void print(const char *s);
extern void print_Dec_3(unsigned int value);
/* Function declaration. */
int test_stuck_address(unsigned long volatile *bufa, size_t count);
int test_random_value(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_xor_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_sub_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_mul_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_div_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_or_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_and_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_seqinc_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_solidbits_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_checkerboard_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_blockseq_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_walkbits0_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_walkbits1_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_bitspread_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_bitflip_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_simple_comparison(ulv *bufa, ulv *bufb, size_t count);