diff options
Diffstat (limited to 'src/mainboard/emulation/qemu-armv7/cbmem.c')
-rw-r--r-- | src/mainboard/emulation/qemu-armv7/cbmem.c | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/src/mainboard/emulation/qemu-armv7/cbmem.c b/src/mainboard/emulation/qemu-armv7/cbmem.c index a626ec6adf..f26ca6cd20 100644 --- a/src/mainboard/emulation/qemu-armv7/cbmem.c +++ b/src/mainboard/emulation/qemu-armv7/cbmem.c @@ -14,8 +14,52 @@ #include <stddef.h> #include <cbmem.h> #include <symbols.h> +#include <arch/io.h> +#include "mainboard.h" + +#define PATTERN1 0x55 +#define PATTERN2 0xaa + +/* Returns 1 if mebibyte mb is present and 0 otherwise. */ +static int probe_mb(int mb) +{ + char *ptr = (char *) 0x60000000 + (mb << 20) + 0xfffff; + char old; + if (ptr < (char *) &_eprogram) { + /* Don't probe below _end to avoid accidentally clobering + oneself. */ + return 1; + } + + old = read8(ptr); + write8(ptr, PATTERN1); + if (read8(ptr) != PATTERN1) + return 0; + write8(ptr, PATTERN2); + if (read8(ptr) != PATTERN2) + return 0; + write8(ptr, old); + return 1; +} + +int probe_ramsize(void) +{ + int i; + int discovered = 0; + static int saved_result; + if (saved_result) + return saved_result; + /* Compact binary search. */ + /* 1 GiB is the largest supported RAM by this machine. */ + for (i = 9; i >= 0; i--) + if (probe_mb(discovered | (1 << i))) + discovered |= (1 << i); + discovered++; + saved_result = discovered; + return discovered; +} void *cbmem_top(void) { - return _dram + (CONFIG_DRAM_SIZE_MB << 20); + return _dram + (probe_ramsize() << 20); } |