Commit 14f73ca679f6fdb44cff0b7304d419db41a0ab69

Authored by Stefan Roese
1 parent c664bf8c3c

ppc: Add CFG_MEM_TOP_HIDE option to hide memory area that doesn't get "touched"

If CFG_MEM_TOP_HIDE is defined in the board config header, this specified
memory area will get subtracted from the top (end) of ram and won't get
"touched" at all by U-Boot. By fixing up gd->ram_size the Linux kernel
should gets passed the now "corrected" memory size and won't touch it
either. This should work for arch/ppc and arch/powerpc. Only Linux board
ports in arch/powerpc with bootwrapper support, which recalculate the
memory size from the SDRAM controller setup, will have to get fixed
in Linux additionally.

This patch enables this config option on some PPC440EPx boards as a workaround
for the CHIP 11 errata. Here the description from the AMCC documentation:

CHIP_11: End of memory range area restricted access.
Category: 3

Overview:
The 440EPx DDR controller does not acknowledge any
transaction which is determined to be crossing over the
end-of-memory-range boundary, even if the starting address is
within valid memory space. Any such transaction from any PLB4
master will result in a PLB time-out on PLB4 bus.

Impact:
In case of such misaligned bursts, PLB4 masters will not
retrieve any data at all, just the available data up to the
end of memory, especially the 440 CPU. For example, if a CPU
instruction required an operand located in memory within the
last 7 words of memory, the DCU master would burst read 8
words to update the data cache and cross over the
end-of-memory-range boundary. Such a DCU read would not be
answered by the DDR controller, resulting in a PLB4 time-out
and ultimately in a Machine Check interrupt. The data would
be inaccessible to the CPU.

Workaround:
Forbid any application to access the last 256 bytes of DDR
memory. For example, make your operating system believe that
the last 256 bytes of DDR memory are absent. AMCC has a patch
that does this, available for Linux.

This patch sets CFG_MEM_TOP_HIDE for the following 440EPx boards:
lwmon5, korat, sequoia

The other remaining 440EPx board were intentionally not included
since it is not clear to me, if they use the end of ram for some
other purpose. This is unclear, since these boards have CONFIG_PRAM
defined and even comments like this:

PMC440.h:
/* esd expects pram at end of physical memory.
 * So no logbuffer at the moment.
 */

It is strongly recommended to not use the last 256 bytes on those
boards too. Patches from the board maintainers are welcome.

Signed-off-by: Stefan Roese <sr@denx.de>

Showing 5 changed files with 41 additions and 1 deletions Side-by-side Diff

... ... @@ -1929,6 +1929,27 @@
1929 1929 Scratch address used by the alternate memory test
1930 1930 You only need to set this if address zero isn't writeable
1931 1931  
  1932 +- CFG_MEM_TOP_HIDE (PPC only):
  1933 + If CFG_MEM_TOP_HIDE is defined in the board config header,
  1934 + this specified memory area will get subtracted from the top
  1935 + (end) of ram and won't get "touched" at all by U-Boot. By
  1936 + fixing up gd->ram_size the Linux kernel should gets passed
  1937 + the now "corrected" memory size and won't touch it either.
  1938 + This should work for arch/ppc and arch/powerpc. Only Linux
  1939 + board ports in arch/powerpc with bootwrapper support, that
  1940 + recalculate the memory size from the SDRAM controller setup
  1941 + will have to get fixed.
  1942 +
  1943 + This option can be used as a workaround for the 440EPx/GRx
  1944 + CHIP 11 errata where the last 256 bytes in SDRAM shouldn't
  1945 + be touched.
  1946 +
  1947 + WARNING: Please make sure that this value is a multiple of
  1948 + the Linux page size (normally 4k). If this is not the case,
  1949 + then the end address of the Linux memory will be located at a
  1950 + non page size aligned address and this could cause major
  1951 + problems.
  1952 +
1932 1953 - CFG_TFTP_LOADADDR:
1933 1954 Default load address for network file downloads
1934 1955  
include/configs/korat.h
... ... @@ -144,6 +144,8 @@
144 144 #define SPD_EEPROM_ADDRESS {0x50}
145 145 #define CONFIG_PROG_SDRAM_TLB
146 146 #define CFG_DRAM_TEST
  147 +#define CFG_MEM_TOP_HIDE (4 << 10) /* don't use last 4kbytes */
  148 + /* 440EPx errata CHIP 11 */
147 149  
148 150 /*
149 151 * I2C
include/configs/lwmon5.h
... ... @@ -86,6 +86,8 @@
86 86 #define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
87 87 #define CFG_POST_ALT_WORD_ADDR (CFG_PERIPHERAL_BASE + GPT0_COMP6)
88 88 /* unused GPT0 COMP reg */
  89 +#define CFG_MEM_TOP_HIDE (4 << 10) /* don't use last 4kbytes */
  90 + /* 440EPx errata CHIP 11 */
89 91  
90 92 /* Additional registers for watchdog timer post test */
91 93  
include/configs/sequoia.h
... ... @@ -221,6 +221,8 @@
221 221 #if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
222 222 #define CONFIG_DDR_DATA_EYE /* use DDR2 optimization */
223 223 #endif
  224 +#define CFG_MEM_TOP_HIDE (4 << 10) /* don't use last 4kbytes */
  225 + /* 440EPx errata CHIP 11 */
224 226  
225 227 /*
226 228 * I2C
... ... @@ -275,7 +277,7 @@
275 277 "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}" \
276 278 ":${hostname}:${netdev}:off panic=1\0" \
277 279 "addtty=setenv bootargs ${bootargs} console=ttyS0,${baudrate}\0"\
278   - "addmisc=setenv bootargs ${bootargs} mem=${mem}\0" \
  280 + "addmisc=setenv bootargs ${bootargs}\0" \
279 281 "flash_nfs=run nfsargs addip addtty addmisc;" \
280 282 "bootm ${kernel_addr}\0" \
281 283 "flash_self=run ramargs addip addtty addmisc;" \
... ... @@ -428,6 +428,7 @@
428 428 * relocate the code and continue running from DRAM.
429 429 *
430 430 * Reserve memory at end of RAM for (top down in that order):
  431 + * - area that won't get touched by U-Boot and Linux (optional)
431 432 * - kernel log buffer
432 433 * - protected RAM
433 434 * - LCD framebuffer
... ... @@ -435,6 +436,18 @@
435 436 * - board info struct
436 437 */
437 438 len = (ulong)&_end - CFG_MONITOR_BASE;
  439 +
  440 + /*
  441 + * Subtract specified amount of memory to hide so that it won't
  442 + * get "touched" at all by U-Boot. By fixing up gd->ram_size
  443 + * the Linux kernel should now get passed the now "corrected"
  444 + * memory size and won't touch it either. This should work
  445 + * for arch/ppc and arch/powerpc. Only Linux board ports in
  446 + * arch/powerpc with bootwrapper support, that recalculate the
  447 + * memory size from the SDRAM controller setup will have to
  448 + * get fixed.
  449 + */
  450 + gd->ram_size -= CFG_MEM_TOP_HIDE;
438 451  
439 452 #ifndef CONFIG_MAX_MEM_MAPPED
440 453 #define CONFIG_MAX_MEM_MAPPED (256 << 20)