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