I am searching for how to test data bus between CPU and memory.
I found the 'walking 1's test' C source code. (link : https://www.esacademy.com/en/library/technical-articles-and-documents/miscellaneous/software-based-memory-testing.html )
So, I compiled the C code to assembly (by ARM gcc) to understand the atomic CPU/memory action in H/W level.
By looking at assembly carefully, I think this doesn't work for testing the data bus.
Here's the C code and assembly.
#define ul unsigned long
ul DataBusTest_Walking_1(volatile ul* address)
{
ul pattern;
for (pattern = 1; pattern != 0; pattern <<= 1)
{
*address = pattern;
if (*address != pattern)
{
return(pattern);
}
}
}
DataBusTest_Walking_1:
push {r7}
sub sp, sp, #20
add r7, sp, #0
str r0, [r7, #4]
movs r3, #1
str r3, [r7, #12]
b .L2
.L5:
ldr r3, [r7, #4]
ldr r2, [r7, #12]
str r2, [r3]
ldr r3, [r7, #4]
ldr r3, [r3]
ldr r2, [r7, #12]
cmp r2, r3
beq .L3
ldr r3, [r7, #12]
b .L1
.L3:
ldr r3, [r7, #12]
lsls r3, r3, #1
str r3, [r7, #12]
.L2:
ldr r3, [r7, #12]
cmp r3, #0
bne .L5
.L1:
mov r0, r3
adds r7, r7, #20
mov sp, r7
ldr r7, [sp], #4
bx lr
I will explain the code briefly.
In C code, write the pattern value into the memory location 'address'.
pattern value changes like this : (walking 1)
0x00000001(00000 ..... 000001)
0x00000002(00000 ..... 000010)
0x00000004(00000 ..... 000100)
0x00000008(00000 ..... 001000) ...
If the data bus has problems, writing pattern value to memory will not work.
So, *address != pattern.
Then, detect the data bus problem.
However, by looking at assembly carefully, I found that a problem exists.
At the beginning of the function DataBusTest_Walking_1, local variable 'pattern' exists in memory.
Before writing 'pattern value' into memory location 'address', CPU should load the 'pattern value' from memory.
And, this is the problem point. When load the 'pattern value', because of the data bus problem, CPU will load incorrect 'pattern value'.
Then, writing the 'incorrect pattern value' to the memory location 'address'.
Then, load the 'incorrect pattern value' from the memory location 'address'.
So, when comparing pattern and *address if (*address != pattern)
, 'incorrect pattern value' == 'incorrect pattern value' happens.
Though the data bus problem exists, we can't detect it finally.
Anyone can prove this test code work?