XO 4 Memory Test: Difference between revisions

From OLPC
Jump to navigation Jump to search
(CL4 memory test)
 
 
(17 intermediate revisions by 2 users not shown)
Line 1: Line 1:
The following information is only needed for debugging the timing parameters for a new DDR3 DRAM for the [[XO-CL4]] laptop.
The following information is only needed for debugging the timing parameters for a new DDR3 DRAM for the [[XO-4]] laptop.


== Memory Configuration ==
== 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:
You will need a [[Serial_adapters|serial cable]] attached to the laptop's host serial port. 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...
CForth built 2012-08-16 02:20 from commit e000ecca...
Skipping OFW
Skipping OFW
ok
ok


'''Some versions of OFW (Q7A00 through Q7A06) automatically initialize the memory controllers before providing the prompt. You cannot change timing parameters using these versions. More details [[#late-init|below]].'''
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.

CForth has 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
ok .table
d100dbc0 : d0001 10
d100dbc0 : e0001 10
d100dbc8 : 42430 20
d100dbc8 : 42530 20
d100dbd0 : 0 30
d100dbd0 : 0 30
d100dbd8 : 911403cf 80
d100dbd8 : 911403cf 80
d100dbe0 : 64660404 84
d100dbe0 : 64660784 84
d100dbe8 : c2004453 88
d100dbe8 : c2004453 88
d100dbf0 : 34f4a187 8c
d100dbf0 : 34f4a187 8c
Line 53: Line 55:
d100dd00 : 200 390
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).
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). It is usually called indirectly, by calling late-init.


===late-init===
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.
After modifying the table, you can initialize the memory using the "late-init" (this calls init-dram after setting the freqs). You can then either [[#Memory_Test_Commands|test the memory]] 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.
'''The memory may only be initialized once.''' late-init (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.


Some versions of OFW (Q7A00 through Q7A06) automatically initialize the memory controllers before providing the prompt. You do not need to type the late-init command with them. Typing it will have no effect. You cannot change timing parameters using these versions. Address mapping and interleave, however, may still be changed.
== Memory Test Commands ==


===Testing 1Gb DDR3 Parts===
In the following commands, if no error is encountered the error address returned is -1 (0xFFFFFFFF).
One example of this is testing a particular new 1Gb DDR3 part, instead of the 2Gb parts the above table was generated for. To do this, first modify the relevant parts of the table (the first two entries):


ok d0001 d100dbc0 l!
lfill ( address length value -- )
ok 42430 d100dbc8 l!
lcheck ( address length value -- error_address )
inc-fill (address length -- )
inc-check (address length -- error_address )
random-fill ( address length -- )
random-check ( address length -- error_address )


Then initialize both DRAM controllers using late-init. Don't forget to set the [[#interleave|interleave]] to something smaller than the amount of memory. And then you can start OFW and boot Linux. This will need to be repeated on each boot.
lfill/lcheck are good for fast bit-level verification.


ok late-init
inc-fill/inc-check are good for checking addressing.
ok 2 d4282ca0 l!
ok ofw


===Direct mucking about===
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.
If you are just modifying an address mapping, interleave, or invalidating a chip select to disable a controller, you can directly modify the memory controller and CPU control registers even if the memory controllers have already been initialized.

You can modify memory controller registers using the mc! (write) and mc@ (read) commands in CForth:

value offset memory_controller mc!
offset memory_controller mc@

These take an argument of 0 or 1 to identify the memory controller.

====Single Memory Controller====
Starting with Q7A07, late-init uses a variable ( #mcs ) to determine how many memory controllers to initialize.

You can configure your laptop to use a single memory controller (the default is two) by setting this variable to 1 before booting. Stop in CForth by holding down the rotate key before powering up the laptop, then on the serial console type:

ok 1 to #mcs
ok late-init ofw

Boot should proceed normally, but with half as much memory as is normal.

===Interleave===

The memory interleave register (DDR_INTERLEAVE_CONTROL) determines the boundary upon which memory controllers are interleaved in the address space. It is located at address 0xD4282CA0. It is a bit field set to zero to disable interleave (not recommended when using two controllers). Bit 0 selects interleaving on a 4KB boundary, bit 1 interleaving on a 16KB boundary, bit 2 a 64 KB boundary, bit 3 a 256 KB boundary, bit 4 a 1024KB boundary, bit 5 a 512 MB boundary, and bit 6 a 1 GB boundary.

For example, to change the system to interleave between memory controllers on a 256KB boundary, type:

ok 8 d4282ca0 l!

And to disable one of the memory controllers, type:

ok 0 d4282ca0 l!
ok 0 10 0 mc!

This sets the interleave to zero, then disables memory controller 0.

== SP Memory Addressing ==


Beware that that the SP's memory addressing is a little strange:
Beware that CForth runs on the SoCs security processor (SP), using physical addressing. The SP's memory addressing is a little strange relative to OFW's physical addressing running on the main core(s), listed as DRAM address:


{| class="wikitable"
{| class="wikitable"
Line 97: Line 134:
| 0x3000.0000
| 0x3000.0000
| inaccessible
| inaccessible
|}

== Memory Test Commands ==

If using a version of CForth which doesn't automatically init the memory (i.e.: a version later than Q7A06), if you run a memory test without first initializing the memory using [[#late-init|late-init]], the processor will silently hang.

=== Canned Test Commands ===

{| class="wikitable"
|-
|-
! 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 ===
If you run a memory test without first initializing the memory using "init-dram", the processor will silently hang.

In the following commands, if an error is encountered, the returns value is the address where the error occurred. If no error is encountered the returned error address is -1 (0xFFFFFFFF).

{| class="wikitable"
|-
! 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, a quick test of the lower 1 MB of memory would be:
For example, to test the lower 1 MB of memory:


0 100000 random-fill
ok 0 100000 random-fill
0 100000 random-check .
ok 0 100000 random-check .


[[Category:Hardware]]
[[Category:Hardware]]
[[Category:XO-CL4]]
[[Category:XO-4]]

Latest revision as of 02:51, 10 October 2012

The following information is only needed for debugging the timing parameters for a new DDR3 DRAM for the XO-4 laptop.

Memory Configuration

You will need a serial cable attached to the laptop's host serial port. 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-08-16 02:20 from commit e000ecca...
Skipping OFW
ok

Some versions of OFW (Q7A00 through Q7A06) automatically initialize the memory controllers before providing the prompt. You cannot change timing parameters using these versions. More details below.

CForth has 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 :    e0001       10
d100dbc8 :    42530       20
d100dbd0 :        0       30
d100dbd8 : 911403cf       80
d100dbe0 : 64660784       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). It is usually called indirectly, by calling late-init.

late-init

After modifying the table, you can initialize the memory using the "late-init" (this calls init-dram after setting the freqs). You can then either test the memory or start OFW using the "ofw" command.

The memory may only be initialized once. late-init (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.

Some versions of OFW (Q7A00 through Q7A06) automatically initialize the memory controllers before providing the prompt. You do not need to type the late-init command with them. Typing it will have no effect. You cannot change timing parameters using these versions. Address mapping and interleave, however, may still be changed.

Testing 1Gb DDR3 Parts

One example of this is testing a particular new 1Gb DDR3 part, instead of the 2Gb parts the above table was generated for. To do this, first modify the relevant parts of the table (the first two entries):

ok  d0001 d100dbc0 l!
ok  42430 d100dbc8 l!

Then initialize both DRAM controllers using late-init. Don't forget to set the interleave to something smaller than the amount of memory. And then you can start OFW and boot Linux. This will need to be repeated on each boot.

ok  late-init
ok  2 d4282ca0 l!
ok  ofw

Direct mucking about

If you are just modifying an address mapping, interleave, or invalidating a chip select to disable a controller, you can directly modify the memory controller and CPU control registers even if the memory controllers have already been initialized.

You can modify memory controller registers using the mc! (write) and mc@ (read) commands in CForth:

value offset memory_controller mc!
offset memory_controller mc@

These take an argument of 0 or 1 to identify the memory controller.

Single Memory Controller

Starting with Q7A07, late-init uses a variable ( #mcs ) to determine how many memory controllers to initialize.

You can configure your laptop to use a single memory controller (the default is two) by setting this variable to 1 before booting. Stop in CForth by holding down the rotate key before powering up the laptop, then on the serial console type:

ok  1 to #mcs
ok  late-init ofw

Boot should proceed normally, but with half as much memory as is normal.

Interleave

The memory interleave register (DDR_INTERLEAVE_CONTROL) determines the boundary upon which memory controllers are interleaved in the address space. It is located at address 0xD4282CA0. It is a bit field set to zero to disable interleave (not recommended when using two controllers). Bit 0 selects interleaving on a 4KB boundary, bit 1 interleaving on a 16KB boundary, bit 2 a 64 KB boundary, bit 3 a 256 KB boundary, bit 4 a 1024KB boundary, bit 5 a 512 MB boundary, and bit 6 a 1 GB boundary.

For example, to change the system to interleave between memory controllers on a 256KB boundary, type:

ok  8 d4282ca0 l!

And to disable one of the memory controllers, type:

ok  0 d4282ca0 l!
ok  0 10 0 mc!

This sets the interleave to zero, then disables memory controller 0.

SP Memory Addressing

Beware that CForth runs on the SoCs security processor (SP), using physical addressing. The SP's memory addressing is a little strange relative to OFW's physical addressing running on the main core(s), listed as DRAM address:

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 using a version of CForth which doesn't automatically init the memory (i.e.: a version later than Q7A06), if you run a memory test without first initializing the memory using late-init, 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 an error is encountered, the returns value is the address where the error occurred. If no error is encountered the returned error address 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:

ok  0 100000 random-fill
ok  0 100000 random-check .