summaryrefslogtreecommitdiff
path: root/common/memsize.c
blob: 5c0d279625a005484f055e19b8dc7183d2c4dd56 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
 * (C) Copyright 2004
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>

DECLARE_GLOBAL_DATA_PTR;

#ifdef __PPC__
/*
 * At least on G2 PowerPC cores, sequential accesses to non-existent
 * memory must be synchronized.
 */
# include <asm/io.h>	/* for sync() */
#else
# define sync()		/* nothing */
#endif

/*
 * Check memory range for valid RAM. A simple memory test determines
 * the actually available RAM size between addresses `base' and
 * `base + maxsize'.
 */
long get_ram_size(long *base, long maxsize)
{
	volatile long *addr;
	long           save[32];
	long           cnt;
	long           val;
	long           size;
	int            i = 0;

	for (cnt = (maxsize / sizeof(long)) >> 1; cnt >= 0; cnt >>= 1) {
		addr = base + cnt;	/* pointer arith! */
		sync();
		save[i] = *addr;
		sync();
		if (cnt) {
			i++;
			*addr = ~cnt;
		} else {
			*addr = 0;
		}
	}

	sync();
	cnt = 0;
	do {
		addr = base + cnt;	/* pointer arith! */
		val = *addr;
		*addr = save[i--];
		sync();
		if (((cnt == 0) && (val != 0)) ||
		    ((cnt != 0) && (val != ~cnt))) {
			size = cnt * sizeof(long);
			/*
			 * Restore the original data
			 * before leaving the function.
			 */
			for (cnt <<= 1;
			     cnt < maxsize / sizeof(long);
			     cnt <<= 1) {
				addr  = base + cnt;
				*addr = save[i--];
			}
			return (size);
		}

		if (cnt)
			cnt = cnt << 1;
		else
			cnt = 1;
	} while (cnt < maxsize / sizeof(long));

	return (maxsize);
}

phys_size_t __weak get_effective_memsize(void)
{
#ifndef CONFIG_VERY_BIG_RAM
	return gd->ram_size;
#else
	/* limit stack to what we can reasonable map */
	return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
		CONFIG_MAX_MEM_MAPPED : gd->ram_size);
#endif
}