XO 4 Memory Test
The following information is only needed for debugging the timing parameters for a new DDR3 DRAM for the XO-CL4 laptop.
Memory Configuration
You will need a serial cable attached. Hold down the "rotate" key (near the screen) while booting the laptop, in order to stop the boot in CForth. You should see something like:
CForth built 2012-07-20 10:11 from commit 12345678... Skipping OFW ok
At this point, the DDR3 memory has not been initialized. There is a table with most of the memory configuration parameters loaded in memory, which you can modify. You can see a listing of this table using the ".table" command. The first column is the actual address in memory of that row of the table. The second column is the value being written to a configuration register. The third column is the offset, relative to the memory controller base address, of the configuration register being written.
ok .table d100dbc0 : d0001 10 d100dbc8 : 42430 20 d100dbd0 : 0 30 d100dbd8 : 911403cf 80 d100dbe0 : 64660404 84 d100dbe8 : c2004453 88 d100dbf0 : 34f4a187 8c d100dbf8 : f20c1 90 d100dc00 : 4040200 94 d100dc08 : 5501 98 d100dc10 : 0 50 d100dc18 : 0 54 d100dc20 : 20c08009 58 d100dc28 : 201 5c d100dc30 : 200000a 60 d100dc38 : 0 64 d100dc40 : 0 68 d100dc48 : 300008 240 d100dc50 : 80000000 24c d100dc58 : 31d8 23c d100dc60 : 20004055 220 d100dc68 : 1ff84a79 230 d100dc70 : ff00a70 234 d100dc78 : a7 238 d100dc80 : f0210000 248 d100dc88 : 0 300 d100dc90 : 1080 304 d100dc98 : 1 300 d100dca0 : 1080 304 d100dca8 : 2 300 d100dcb0 : 1080 304 d100dcb8 : 3 300 d100dcc0 : 1080 304 d100dcc8 : 100 380 d100dcd0 : 200 390 d100dcd8 : 101 380 d100dce0 : 200 390 d100dce8 : 102 380 d100dcf0 : 200 390 d100dcf8 : 103 380 d100dd00 : 200 390
The offset is relative to the memory controller base address which is 0xd001.0000 for memory controller 0 and 0xd000.0000 for memory controller 1. The table values are first written to memory controller 0, then its DLL is initialized, and then the process is repeated for memory controller 1. Finally, the interleave is configured by writing to the DDR_ILV_CTRL register at 0xd4282ca0 . See the Forth word "init-dram" for details (cforth/src/app/arm-xo-cl4/initdram.fth).
After modifying the table, you can initialize the memory using the "init-dram". You can then either test the memory (see below) or start OFW using the "ofw" command.
The memory may only be initialized once. init-dram only works the first time (it doesn't even try after that). To test a different memory configuration you need to power cycle the laptop.
SP Memory Addressing
Beware that that the SP's memory addressing is a little strange:
DRAM address | SP address |
---|---|
0x0000.0000 | 0x0000.0000 (if TCM is off; memory inaccessible via SP address 0 with TCM on) |
0x0000.0000 | 0x1000.0000 |
0x1000.0000 | 0x2000.0000 |
0x2000.0000 | 0x3000.0000 |
0x3000.0000 | inaccessible |
Memory Test Commands
If you run a memory test without first initializing the memory using "init-dram", the processor will silently hang.
Canned Test Commands
Command | Stack | Description |
---|---|---|
memtest | ( ) | Runs a random-pattern test (see below) and reports the result |
memtest-start | ( -- address ) | Value containing the start address for memtest |
memtest-length | ( -- length ) | Value containing the length for memtest |
2000.0000 to memtest-start | Change the memtest start address | |
1000.0000 to memtest-length | Change the memtest length |
Test Primitives for Detailed Debugging
In the following commands, if no error is encountered the error address returned is -1 (0xFFFFFFFF).
Command | Stack | Description |
---|---|---|
lfill | ( address length value -- ) | Fill memory range with 32-bit value |
lcheck | ( address length value -- error_address ) | Check the result of lfill |
inc-fill | (address length -- ) | Fill memory range with data=address |
inc-check | (address length -- error_address ) | Check the result of inc-fill |
random-fill | ( address length -- ) | Fill memory range with psuedorandom data using a pseudorandom access order |
random-check | ( address length -- error_address ) | Check the result of random-fill |
lfill/lcheck are good for fast bit-level verification.
inc-fill/inc-check are good for checking addressing.
random-fill/random-check are somewhat slower. They are good for thorough checkout, but if there are problems, it can be difficult to determine the exact problem syndrome, since the test pattern is not easily recognizable.
For example, to test the lower 1 MB of memory:
0 100000 random-fill 0 100000 random-check .