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 11 DECLARE_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 */ get_ram_size(long * base,long maxsize)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 get_effective_memsize(void)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