]> Git Repo - J-u-boot.git/blame - common/memsize.c
Merge patch series "Move DRAM address of ATF"
[J-u-boot.git] / common / memsize.c
CommitLineData
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>
1c64b98c
EG
10#include <cpu_func.h>
11#include <stdint.h>
e3866163
YS
12
13DECLARE_GLOBAL_DATA_PTR;
14
1c64b98c
EG
15#ifdef CONFIG_SYS_CACHELINE_SIZE
16# define MEMSIZE_CACHELINE_SIZE CONFIG_SYS_CACHELINE_SIZE
17#else
18/* Just use the greatest cache flush alignment requirement I'm aware of */
19# define MEMSIZE_CACHELINE_SIZE 128
20#endif
21
91650b3e
WD
22#ifdef __PPC__
23/*
24 * At least on G2 PowerPC cores, sequential accesses to non-existent
25 * memory must be synchronized.
26 */
27# include <asm/io.h> /* for sync() */
28#else
29# define sync() /* nothing */
30#endif
c83bf6a2 31
1c64b98c
EG
32static void dcache_flush_invalidate(volatile long *p)
33{
34 uintptr_t start, stop;
35 start = ALIGN_DOWN((uintptr_t)p, MEMSIZE_CACHELINE_SIZE);
36 stop = start + MEMSIZE_CACHELINE_SIZE;
37 flush_dcache_range(start, stop);
38 invalidate_dcache_range(start, stop);
39}
40
c83bf6a2
WD
41/*
42 * Check memory range for valid RAM. A simple memory test determines
43 * the actually available RAM size between addresses `base' and
44 * `base + maxsize'.
45 */
a55d23cc 46long get_ram_size(long *base, long maxsize)
c83bf6a2
WD
47{
48 volatile long *addr;
67a2616a 49 long save[BITS_PER_LONG - 1];
c5da05cd 50 long save_base;
c83bf6a2
WD
51 long cnt;
52 long val;
53 long size;
54 int i = 0;
1c64b98c 55 int dcache_en = dcache_status();
c83bf6a2 56
cc8d698f 57 for (cnt = (maxsize / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
c83bf6a2 58 addr = base + cnt; /* pointer arith! */
95099fee 59 sync();
cc8d698f 60 save[i++] = *addr;
95099fee 61 sync();
cc8d698f 62 *addr = ~cnt;
1c64b98c
EG
63 if (dcache_en)
64 dcache_flush_invalidate(addr);
c83bf6a2
WD
65 }
66
cc8d698f
HG
67 addr = base;
68 sync();
c5da05cd 69 save_base = *addr;
cc8d698f
HG
70 sync();
71 *addr = 0;
72
8e7cba04 73 sync();
1c64b98c
EG
74 if (dcache_en)
75 dcache_flush_invalidate(addr);
76
cc8d698f
HG
77 if ((val = *addr) != 0) {
78 /* Restore the original data before leaving the function. */
79 sync();
c5da05cd 80 *base = save_base;
cc8d698f
HG
81 for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) {
82 addr = base + cnt;
83 sync();
84 *addr = save[--i];
85 }
86 return (0);
87 }
88
89 for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) {
c83bf6a2
WD
90 addr = base + cnt; /* pointer arith! */
91 val = *addr;
cc8d698f
HG
92 *addr = save[--i];
93 if (val != ~cnt) {
95099fee
WD
94 size = cnt * sizeof(long);
95 /*
96 * Restore the original data
97 * before leaving the function.
c83bf6a2 98 */
95099fee
WD
99 for (cnt <<= 1;
100 cnt < maxsize / sizeof(long);
101 cnt <<= 1) {
c83bf6a2 102 addr = base + cnt;
cc8d698f 103 *addr = save[--i];
c83bf6a2 104 }
218da804
PD
105 /* warning: don't restore save_base in this case,
106 * it is already done in the loop because
107 * base and base+size share the same physical memory
108 * and *base is saved after *(base+size) modification
109 * in first loop
110 */
c83bf6a2
WD
111 return (size);
112 }
cc8d698f 113 }
218da804 114 *base = save_base;
c83bf6a2
WD
115
116 return (maxsize);
117}
e3866163
YS
118
119phys_size_t __weak get_effective_memsize(void)
120{
777aaaa7
T
121 phys_size_t ram_size = gd->ram_size;
122
d1f4b090 123#ifdef CONFIG_MPC85xx
777aaaa7
T
124 /*
125 * Check for overflow and limit ram size to some representable value.
126 * It is required that ram_base + ram_size must be representable by
127 * phys_size_t type and must be aligned by direct access, therefore
128 * calculate it from last 4kB sector which should work as alignment
129 * on any platform.
130 */
131 if (gd->ram_base + ram_size < gd->ram_base)
132 ram_size = ((phys_size_t)~0xfffULL) - gd->ram_base;
d1f4b090 133#endif
777aaaa7 134
1d457dbb 135#ifndef CFG_MAX_MEM_MAPPED
777aaaa7 136 return ram_size;
e3866163
YS
137#else
138 /* limit stack to what we can reasonable map */
1d457dbb
TR
139 return ((ram_size > CFG_MAX_MEM_MAPPED) ?
140 CFG_MAX_MEM_MAPPED : ram_size);
e3866163
YS
141#endif
142}
This page took 0.574971 seconds and 4 git commands to generate.