mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 21:07:02 +09:00
memtester support in kernel
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
19
arch/arm/mach-rk29/include/mach/memtester.h
Executable file
19
arch/arm/mach-rk29/include/mach/memtester.h
Executable 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
177
arch/arm/mach-rk29/memtester.c
Executable 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;
|
||||
}
|
||||
@@ -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
515
arch/arm/mach-rk29/tests.c
Executable 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
195
arch/arm/mach-rk29/tests.h
Executable 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);
|
||||
|
||||
Reference in New Issue
Block a user