uboot/common/memsize.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2004
   4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   5 */
   6
   7#include <common.h>
   8#include <init.h>
   9#include <asm/global_data.h>
  10
  11DECLARE_GLOBAL_DATA_PTR;
  12
  13#ifdef __PPC__
  14/*
  15 * At least on G2 PowerPC cores, sequential accesses to non-existent
  16 * memory must be synchronized.
  17 */
  18# include <asm/io.h>    /* for sync() */
  19#else
  20# define sync()         /* nothing */
  21#endif
  22
  23/*
  24 * Check memory range for valid RAM. A simple memory test determines
  25 * the actually available RAM size between addresses `base' and
  26 * `base + maxsize'.
  27 */
  28long get_ram_size(long *base, long maxsize)
  29{
  30        volatile long *addr;
  31        long           save[BITS_PER_LONG - 1];
  32        long           save_base;
  33        long           cnt;
  34        long           val;
  35        long           size;
  36        int            i = 0;
  37
  38        for (cnt = (maxsize / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
  39                addr = base + cnt;      /* pointer arith! */
  40                sync();
  41                save[i++] = *addr;
  42                sync();
  43                *addr = ~cnt;
  44        }
  45
  46        addr = base;
  47        sync();
  48        save_base = *addr;
  49        sync();
  50        *addr = 0;
  51
  52        sync();
  53        if ((val = *addr) != 0) {
  54                /* Restore the original data before leaving the function. */
  55                sync();
  56                *base = save_base;
  57                for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) {
  58                        addr  = base + cnt;
  59                        sync();
  60                        *addr = save[--i];
  61                }
  62                return (0);
  63        }
  64
  65        for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) {
  66                addr = base + cnt;      /* pointer arith! */
  67                val = *addr;
  68                *addr = save[--i];
  69                if (val != ~cnt) {
  70                        size = cnt * sizeof(long);
  71                        /*
  72                         * Restore the original data
  73                         * before leaving the function.
  74                         */
  75                        for (cnt <<= 1;
  76                             cnt < maxsize / sizeof(long);
  77                             cnt <<= 1) {
  78                                addr  = base + cnt;
  79                                *addr = save[--i];
  80                        }
  81                        /* warning: don't restore save_base in this case,
  82                         * it is already done in the loop because
  83                         * base and base+size share the same physical memory
  84                         * and *base is saved after *(base+size) modification
  85                         * in first loop
  86                         */
  87                        return (size);
  88                }
  89        }
  90        *base = save_base;
  91
  92        return (maxsize);
  93}
  94
  95phys_size_t __weak get_effective_memsize(void)
  96{
  97#ifndef CONFIG_VERY_BIG_RAM
  98        return gd->ram_size;
  99#else
 100        /* limit stack to what we can reasonable map */
 101        return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
 102                CONFIG_MAX_MEM_MAPPED : gd->ram_size);
 103#endif
 104}
 105