1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright Siemens AG 2020
*
* SPL Full Memory Test
* - memory test through the full DDR area
* - refresh over temperature torture (write all, read all)
*
* Remark:
* This test has ran properly with the definition of the RAM sizes in board
* headers. Since these headers are removed it's necessary to set the correct
* values to PHYS_SDRAM_1_SIZE & PHYS_SDRAM_2_SIZE before to recompile.
*
* An alternative is to refactor the code to get the size info from system
* controller
*/
#include <init.h>
#include <log.h>
/* ----- Defines ----- */
#define CHECK_LOWER_UPPER
#define LEVEL2_PRINT 0x0FFFFFFF
/* use 0x7FFF0000 for shorter loop test */
#define BASE_OFFSET 0x00000000
/* ----- Types ----- */
struct ct_t {
unsigned long *start;
unsigned long *end;
};
/* ----- Variables ----- */
static struct ct_t ct;
static unsigned long error_counter;
static void print_parameters(void)
{
printf("\nstart addr: %p\n", ct.start);
printf("end addr : %p\n", ct.end);
}
static void run_test(void)
{
/* moved full test in one void */
unsigned long *address; /* 512 */
unsigned long ebyte1;
unsigned long ebyte2;
unsigned int i;
unsigned long rpattern;
for (i = 0; i <= 255; i++) {
memset(&ebyte1, i, sizeof(ebyte1));
ebyte2 = ~ebyte1;
printf("LWord: %016lx #LWord: %016lx\n", ebyte1, ebyte2);
/* write all bytes -> duration ~ 150 s */
for (address = ct.start; address <= ct.end; address++) {
#ifdef LEVEL2_PRINT
if (((unsigned long)address & LEVEL2_PRINT) == 0)
printf("write to %p - %p\n", address,
(void *)((unsigned long)address +
LEVEL2_PRINT));
#endif
*address = ebyte1;
address++;
*address = ebyte2;
}
/* check all bytes */
for (address = ct.start; address <= ct.end; address++) {
#ifdef LEVEL2_PRINT
if (((unsigned long)address & LEVEL2_PRINT) == 0)
printf("check from %p - %p\n", address,
(void *)((unsigned long)address +
LEVEL2_PRINT));
#endif
rpattern = *address;
if (rpattern != ebyte1) {
error_counter++;
printf("Error! Read: %016lX Wrote: %016lX Address: %p\n",
rpattern, ebyte1, address);
}
address++;
rpattern = *address;
if (rpattern != ebyte2) {
error_counter++;
printf("Error! Read: %016lX Wrote: %016lX Address: %p\n",
rpattern, ebyte2, address);
}
}
}
}
#ifdef CHECK_LOWER_UPPER
void test_lower_upper(void)
{
/*
* write different values at the same address of both memory areas
* and check them
*/
#define TEST_ADDRESS 0x12345670UL
#define LOWER_ADDRESS (PHYS_SDRAM_1 + TEST_ADDRESS)
#define UPPER_ADDRESS (PHYS_SDRAM_2 + TEST_ADDRESS)
#define LOWER_VALUE 0x0011223344556677
#define UPPER_VALUE 0x89ab89abffeeddcc
*(unsigned long *)LOWER_ADDRESS = LOWER_VALUE;
*(unsigned long *)UPPER_ADDRESS = UPPER_VALUE;
puts("\nlower-upper memory area test\n");
printf("write %016lx to lower address %010lx\n", LOWER_VALUE,
LOWER_ADDRESS);
printf("write %016lx to upper address %010lx\n", UPPER_VALUE,
UPPER_ADDRESS);
printf("read %016lx from lower address %010lx\n",
*(unsigned long *)LOWER_ADDRESS, LOWER_ADDRESS);
printf("read %016lx from upper address %010lx\n",
*(unsigned long *)UPPER_ADDRESS, UPPER_ADDRESS);
}
#endif
void spl_siemens_memory_full_test(void)
{
unsigned long loopc = 0;
puts("\nSPL: memory cell test\n");
#ifdef CHECK_LOWER_UPPER
if (PHYS_SDRAM_2_SIZE != 0)
test_lower_upper();
#endif
while (true) {
/* imx8x has 2 memory areas up to 2 GB */
/* 1st memory area @ 0x80000000 */
ct.start = (unsigned long *)(PHYS_SDRAM_1 + BASE_OFFSET);
ct.end = (unsigned long *)(PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE - 1);
print_parameters();
run_test();
/* 2nd memory area @ 0x880000000 */
if (PHYS_SDRAM_2_SIZE != 0) {
ct.start = (unsigned long *)(PHYS_SDRAM_2 + BASE_OFFSET);
ct.end = (unsigned long *)(PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE - 1);
print_parameters();
run_test();
}
loopc++;
printf("loop: %ld, errors: %ld\n\n", loopc, error_counter);
};
}
|