]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
c83bf6a2 WD |
2 | /* |
3 | * (C) Copyright 2004 | |
4 | * Wolfgang Denk, DENX Software Engineering, [email protected]. | |
c83bf6a2 WD |
5 | */ |
6 | ||
e3866163 | 7 | #include <common.h> |
9b4a205f | 8 | #include <init.h> |
401d1c4f | 9 | #include <asm/global_data.h> |
e3866163 YS |
10 | |
11 | DECLARE_GLOBAL_DATA_PTR; | |
12 | ||
91650b3e WD |
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 | |
c83bf6a2 WD |
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 | */ | |
a55d23cc | 28 | long get_ram_size(long *base, long maxsize) |
c83bf6a2 WD |
29 | { |
30 | volatile long *addr; | |
67a2616a | 31 | long save[BITS_PER_LONG - 1]; |
c5da05cd | 32 | long save_base; |
c83bf6a2 WD |
33 | long cnt; |
34 | long val; | |
35 | long size; | |
36 | int i = 0; | |
37 | ||
cc8d698f | 38 | for (cnt = (maxsize / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) { |
c83bf6a2 | 39 | addr = base + cnt; /* pointer arith! */ |
95099fee | 40 | sync(); |
cc8d698f | 41 | save[i++] = *addr; |
95099fee | 42 | sync(); |
cc8d698f | 43 | *addr = ~cnt; |
c83bf6a2 WD |
44 | } |
45 | ||
cc8d698f HG |
46 | addr = base; |
47 | sync(); | |
c5da05cd | 48 | save_base = *addr; |
cc8d698f HG |
49 | sync(); |
50 | *addr = 0; | |
51 | ||
8e7cba04 | 52 | sync(); |
cc8d698f HG |
53 | if ((val = *addr) != 0) { |
54 | /* Restore the original data before leaving the function. */ | |
55 | sync(); | |
c5da05cd | 56 | *base = save_base; |
cc8d698f HG |
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) { | |
c83bf6a2 WD |
66 | addr = base + cnt; /* pointer arith! */ |
67 | val = *addr; | |
cc8d698f HG |
68 | *addr = save[--i]; |
69 | if (val != ~cnt) { | |
95099fee WD |
70 | size = cnt * sizeof(long); |
71 | /* | |
72 | * Restore the original data | |
73 | * before leaving the function. | |
c83bf6a2 | 74 | */ |
95099fee WD |
75 | for (cnt <<= 1; |
76 | cnt < maxsize / sizeof(long); | |
77 | cnt <<= 1) { | |
c83bf6a2 | 78 | addr = base + cnt; |
cc8d698f | 79 | *addr = save[--i]; |
c83bf6a2 | 80 | } |
218da804 PD |
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 | */ | |
c83bf6a2 WD |
87 | return (size); |
88 | } | |
cc8d698f | 89 | } |
218da804 | 90 | *base = save_base; |
c83bf6a2 WD |
91 | |
92 | return (maxsize); | |
93 | } | |
e3866163 YS |
94 | |
95 | phys_size_t __weak get_effective_memsize(void) | |
96 | { | |
777aaaa7 T |
97 | phys_size_t ram_size = gd->ram_size; |
98 | ||
d1f4b090 | 99 | #ifdef CONFIG_MPC85xx |
777aaaa7 T |
100 | /* |
101 | * Check for overflow and limit ram size to some representable value. | |
102 | * It is required that ram_base + ram_size must be representable by | |
103 | * phys_size_t type and must be aligned by direct access, therefore | |
104 | * calculate it from last 4kB sector which should work as alignment | |
105 | * on any platform. | |
106 | */ | |
107 | if (gd->ram_base + ram_size < gd->ram_base) | |
108 | ram_size = ((phys_size_t)~0xfffULL) - gd->ram_base; | |
d1f4b090 | 109 | #endif |
777aaaa7 | 110 | |
1d457dbb | 111 | #ifndef CFG_MAX_MEM_MAPPED |
777aaaa7 | 112 | return ram_size; |
e3866163 YS |
113 | #else |
114 | /* limit stack to what we can reasonable map */ | |
1d457dbb TR |
115 | return ((ram_size > CFG_MAX_MEM_MAPPED) ? |
116 | CFG_MAX_MEM_MAPPED : ram_size); | |
e3866163 YS |
117 | #endif |
118 | } |