|  | The most frequent cause of problems when porting U-Boot to new | 
|  | hardware, or when using a sloppy port on some board, is memory errors. | 
|  | In most cases these are not caused by failing hardware, but by | 
|  | incorrect initialization of the memory controller.  So it appears to | 
|  | be a good idea to always test if the memory is working correctly, | 
|  | before looking for any other potential causes of any problems. | 
|  |  | 
|  | U-Boot implements 3 different approaches to perform memory tests: | 
|  |  | 
|  | 1. The get_ram_size() function (see "common/memsize.c"). | 
|  |  | 
|  | This function is supposed to be used in each and every U-Boot port | 
|  | determine the presence and actual size of each of the potential | 
|  | memory banks on this piece of hardware.  The code is supposed to be | 
|  | very fast, so running it for each reboot does not hurt.  It is a | 
|  | little known and generally underrated fact that this code will also | 
|  | catch 99% of hardware related (i. e. reliably reproducible) memory | 
|  | errors.  It is strongly recommended to always use this function, in | 
|  | each and every port of U-Boot. | 
|  |  | 
|  | 2. The "mtest" command. | 
|  |  | 
|  | This is probably the best known memory test utility in U-Boot. | 
|  | Unfortunately, it is also the most problematic, and the most | 
|  | useless one. | 
|  |  | 
|  | There are a number of serious problems with this command: | 
|  |  | 
|  | - It is terribly slow.  Running "mtest" on the whole system RAM | 
|  | takes a _long_ time before there is any significance in the fact | 
|  | that no errors have been found so far. | 
|  |  | 
|  | - It is difficult to configure, and to use.  And any errors here | 
|  | will reliably crash or hang your system.  "mtest" is dumb and has | 
|  | no knowledge about memory ranges that may be in use for other | 
|  | purposes, like exception code, U-Boot code and data, stack, | 
|  | malloc arena, video buffer, log buffer, etc.  If you let it, it | 
|  | will happily "test" all such areas, which of course will cause | 
|  | some problems. | 
|  |  | 
|  | - It is not easy to configure and use, and a large number of | 
|  | systems are seriously misconfigured.  The original idea was to | 
|  | test basically the whole system RAM, with only exempting the | 
|  | areas used by U-Boot itself - on most systems these are the areas | 
|  | used for the exception vectors (usually at the very lower end of | 
|  | system memory) and for U-Boot (code, data, etc. - see above; | 
|  | these are usually at the very upper end of system memory).  But | 
|  | experience has shown that a very large number of ports use | 
|  | pretty much bogus settings of CONFIG_SYS_MEMTEST_START and | 
|  | CONFIG_SYS_MEMTEST_END; this results in useless tests (because | 
|  | the ranges is too small and/or badly located) or in critical | 
|  | failures (system crashes). | 
|  |  | 
|  | Because of these issues, the "mtest" command is considered depre- | 
|  | cated.  It should not be enabled in most normal ports of U-Boot, | 
|  | especially not in production.  If you really need a memory test, | 
|  | then see 1. and 3. above resp. below. | 
|  |  | 
|  | 3. The most thorough memory test facility is available as part of the | 
|  | POST (Power-On Self Test) sub-system, see "post/drivers/memory.c". | 
|  |  | 
|  | If you really need to perform memory tests (for example, because | 
|  | it is mandatory part of your requirement specification), then | 
|  | enable this test which is generic and should work on all archi- | 
|  | tectures. | 
|  |  | 
|  | WARNING: | 
|  |  | 
|  | It should pointed out that _all_ these memory tests have one | 
|  | fundamental, unfixable design flaw:  they are based on the assumption | 
|  | that memory errors can be found by writing to and reading from memory. | 
|  | Unfortunately, this is only true for the relatively harmless, usually | 
|  | static errors like shorts between data or address lines, unconnected | 
|  | pins, etc.  All the really nasty errors which will first turn your | 
|  | hair gray, only to make you tear it out later, are dynamical errors, | 
|  | which usually happen not with simple read or write cycles on the bus, | 
|  | but when performing back-to-back data transfers in burst mode.  Such | 
|  | accesses usually happen only for certain DMA operations, or for heavy | 
|  | cache use (instruction fetching, cache flushing).  So far I am not | 
|  | aware of any freely available code that implements a generic, and | 
|  | efficient, memory test like that.  The best known test case to stress | 
|  | a system like that is to boot Linux with root file system mounted over | 
|  | NFS, and then build some larger software package natively (say, | 
|  | compile a Linux kernel on the system) - this will cause enough context | 
|  | switches, network traffic (and thus DMA transfers from the network | 
|  | controller), varying RAM use, etc. to trigger any weak spots in this | 
|  | area. | 
|  |  | 
|  | Note: An attempt was made once to implement such a test to catch | 
|  | memory problems on a specific board.  The code is pretty much board | 
|  | specific (for example, it includes setting specific GPIO signals to | 
|  | provide triggers for an attached logic analyzer), but you can get an | 
|  | idea how it works: see "examples/standalone/test_burst*". | 
|  |  | 
|  | Note 2: Ironically enough, the "test_burst" did not catch any RAM | 
|  | errors, not a single one ever.  The problems this code was supposed | 
|  | to catch did not happen when accessing the RAM, but when reading from | 
|  | NOR flash. |