1 /* 2 * (C) Copyright 2004 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <config.h> 9 #ifdef __PPC__ 10 /* 11 * At least on G2 PowerPC cores, sequential accesses to non-existent 12 * memory must be synchronized. 13 */ 14 # include <asm/io.h> /* for sync() */ 15 #else 16 # define sync() /* nothing */ 17 #endif 18 19 /* 20 * Check memory range for valid RAM. A simple memory test determines 21 * the actually available RAM size between addresses `base' and 22 * `base + maxsize'. 23 */ 24 long get_ram_size(long *base, long maxsize) 25 { 26 volatile long *addr; 27 long save[32]; 28 long cnt; 29 long val; 30 long size; 31 int i = 0; 32 33 for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) { 34 addr = base + cnt; /* pointer arith! */ 35 sync (); 36 save[i++] = *addr; 37 sync (); 38 *addr = ~cnt; 39 } 40 41 addr = base; 42 sync (); 43 save[i] = *addr; 44 sync (); 45 *addr = 0; 46 47 sync (); 48 if ((val = *addr) != 0) { 49 /* Restore the original data before leaving the function. 50 */ 51 sync (); 52 *addr = save[i]; 53 for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) { 54 addr = base + cnt; 55 sync (); 56 *addr = save[--i]; 57 } 58 return (0); 59 } 60 61 for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) { 62 addr = base + cnt; /* pointer arith! */ 63 val = *addr; 64 *addr = save[--i]; 65 if (val != ~cnt) { 66 size = cnt * sizeof (long); 67 /* Restore the original data before leaving the function. 68 */ 69 for (cnt <<= 1; cnt < maxsize / sizeof (long); cnt <<= 1) { 70 addr = base + cnt; 71 *addr = save[--i]; 72 } 73 return (size); 74 } 75 } 76 77 return (maxsize); 78 } 79