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