183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 2c83bf6a2Swdenk /* 3c83bf6a2Swdenk * (C) Copyright 2004 4c83bf6a2Swdenk * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 5c83bf6a2Swdenk */ 6c83bf6a2Swdenk 7e3866163SYork Sun #include <common.h> 8e3866163SYork Sun 9e3866163SYork Sun DECLARE_GLOBAL_DATA_PTR; 10e3866163SYork Sun 1191650b3eSWolfgang Denk #ifdef __PPC__ 1291650b3eSWolfgang Denk /* 1391650b3eSWolfgang Denk * At least on G2 PowerPC cores, sequential accesses to non-existent 1491650b3eSWolfgang Denk * memory must be synchronized. 1591650b3eSWolfgang Denk */ 1691650b3eSWolfgang Denk # include <asm/io.h> /* for sync() */ 1791650b3eSWolfgang Denk #else 1891650b3eSWolfgang Denk # define sync() /* nothing */ 1991650b3eSWolfgang Denk #endif 20c83bf6a2Swdenk 21c83bf6a2Swdenk /* 22c83bf6a2Swdenk * Check memory range for valid RAM. A simple memory test determines 23c83bf6a2Swdenk * the actually available RAM size between addresses `base' and 24c83bf6a2Swdenk * `base + maxsize'. 25c83bf6a2Swdenk */ get_ram_size(long * base,long maxsize)26a55d23ccSAlbert ARIBAUDlong get_ram_size(long *base, long maxsize) 27c83bf6a2Swdenk { 28c83bf6a2Swdenk volatile long *addr; 29*67a2616aSTien Fong Chee long save[BITS_PER_LONG - 1]; 30c5da05cdSPatrick Delaunay long save_base; 31c83bf6a2Swdenk long cnt; 32c83bf6a2Swdenk long val; 33c83bf6a2Swdenk long size; 34c83bf6a2Swdenk int i = 0; 35c83bf6a2Swdenk 36cc8d698fSHans de Goede for (cnt = (maxsize / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) { 37c83bf6a2Swdenk addr = base + cnt; /* pointer arith! */ 3891650b3eSWolfgang Denk sync(); 39cc8d698fSHans de Goede save[i++] = *addr; 40cc8d698fSHans de Goede sync(); 41cc8d698fSHans de Goede *addr = ~cnt; 42cc8d698fSHans de Goede } 43cc8d698fSHans de Goede 44cc8d698fSHans de Goede addr = base; 45cc8d698fSHans de Goede sync(); 46c5da05cdSPatrick Delaunay save_base = *addr; 4791650b3eSWolfgang Denk sync(); 48c83bf6a2Swdenk *addr = 0; 49c83bf6a2Swdenk 508e7cba04SEddy Petrișor sync(); 51cc8d698fSHans de Goede if ((val = *addr) != 0) { 52cc8d698fSHans de Goede /* Restore the original data before leaving the function. */ 53cc8d698fSHans de Goede sync(); 54c5da05cdSPatrick Delaunay *base = save_base; 55cc8d698fSHans de Goede for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) { 56cc8d698fSHans de Goede addr = base + cnt; 57cc8d698fSHans de Goede sync(); 58cc8d698fSHans de Goede *addr = save[--i]; 59cc8d698fSHans de Goede } 60cc8d698fSHans de Goede return (0); 61cc8d698fSHans de Goede } 62cc8d698fSHans de Goede 63cc8d698fSHans de Goede for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) { 64c83bf6a2Swdenk addr = base + cnt; /* pointer arith! */ 65c83bf6a2Swdenk val = *addr; 66cc8d698fSHans de Goede *addr = save[--i]; 67cc8d698fSHans de Goede if (val != ~cnt) { 68c83bf6a2Swdenk size = cnt * sizeof(long); 6995099feeSWolfgang Denk /* 7095099feeSWolfgang Denk * Restore the original data 7195099feeSWolfgang Denk * before leaving the function. 72c83bf6a2Swdenk */ 7395099feeSWolfgang Denk for (cnt <<= 1; 7495099feeSWolfgang Denk cnt < maxsize / sizeof(long); 7595099feeSWolfgang Denk cnt <<= 1) { 76c83bf6a2Swdenk addr = base + cnt; 77cc8d698fSHans de Goede *addr = save[--i]; 78c83bf6a2Swdenk } 79218da804SPatrick Delaunay /* warning: don't restore save_base in this case, 80218da804SPatrick Delaunay * it is already done in the loop because 81218da804SPatrick Delaunay * base and base+size share the same physical memory 82218da804SPatrick Delaunay * and *base is saved after *(base+size) modification 83218da804SPatrick Delaunay * in first loop 84218da804SPatrick Delaunay */ 85c83bf6a2Swdenk return (size); 86c83bf6a2Swdenk } 87cc8d698fSHans de Goede } 88218da804SPatrick Delaunay *base = save_base; 89c83bf6a2Swdenk 90c83bf6a2Swdenk return (maxsize); 91c83bf6a2Swdenk } 92e3866163SYork Sun get_effective_memsize(void)93e3866163SYork Sunphys_size_t __weak get_effective_memsize(void) 94e3866163SYork Sun { 95e3866163SYork Sun #ifndef CONFIG_VERY_BIG_RAM 96e3866163SYork Sun return gd->ram_size; 97e3866163SYork Sun #else 98e3866163SYork Sun /* limit stack to what we can reasonable map */ 99e3866163SYork Sun return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ? 100e3866163SYork Sun CONFIG_MAX_MEM_MAPPED : gd->ram_size); 101e3866163SYork Sun #endif 102e3866163SYork Sun } 103