aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/e820_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/e820_64.c')
-rw-r--r--arch/x86/kernel/e820_64.c196
1 files changed, 0 insertions, 196 deletions
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c
index 354fbb221709..07941b554519 100644
--- a/arch/x86/kernel/e820_64.c
+++ b/arch/x86/kernel/e820_64.c
@@ -47,202 +47,6 @@ unsigned long max_pfn_mapped;
47static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT; 47static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT;
48 48
49/* 49/*
50 * Early reserved memory areas.
51 */
52#define MAX_EARLY_RES 20
53
54struct early_res {
55 unsigned long start, end;
56 char name[16];
57};
58static struct early_res early_res[MAX_EARLY_RES] __initdata = {
59 { 0, PAGE_SIZE, "BIOS data page" }, /* BIOS data page */
60#ifdef CONFIG_X86_TRAMPOLINE
61 { TRAMPOLINE_BASE, TRAMPOLINE_BASE + 2 * PAGE_SIZE, "TRAMPOLINE" },
62#endif
63 {}
64};
65
66void __init reserve_early(unsigned long start, unsigned long end, char *name)
67{
68 int i;
69 struct early_res *r;
70 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
71 r = &early_res[i];
72 if (end > r->start && start < r->end)
73 panic("Overlapping early reservations %lx-%lx %s to %lx-%lx %s\n",
74 start, end - 1, name?name:"", r->start, r->end - 1, r->name);
75 }
76 if (i >= MAX_EARLY_RES)
77 panic("Too many early reservations");
78 r = &early_res[i];
79 r->start = start;
80 r->end = end;
81 if (name)
82 strncpy(r->name, name, sizeof(r->name) - 1);
83}
84
85void __init free_early(unsigned long start, unsigned long end)
86{
87 struct early_res *r;
88 int i, j;
89
90 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
91 r = &early_res[i];
92 if (start == r->start && end == r->end)
93 break;
94 }
95 if (i >= MAX_EARLY_RES || !early_res[i].end)
96 panic("free_early on not reserved area: %lx-%lx!", start, end);
97
98 for (j = i + 1; j < MAX_EARLY_RES && early_res[j].end; j++)
99 ;
100
101 memmove(&early_res[i], &early_res[i + 1],
102 (j - 1 - i) * sizeof(struct early_res));
103
104 early_res[j - 1].end = 0;
105}
106
107void __init early_res_to_bootmem(unsigned long start, unsigned long end)
108{
109 int i;
110 unsigned long final_start, final_end;
111 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
112 struct early_res *r = &early_res[i];
113 final_start = max(start, r->start);
114 final_end = min(end, r->end);
115 if (final_start >= final_end)
116 continue;
117 printk(KERN_INFO " early res: %d [%lx-%lx] %s\n", i,
118 final_start, final_end - 1, r->name);
119 reserve_bootmem_generic(final_start, final_end - final_start);
120 }
121}
122
123/* Check for already reserved areas */
124static inline int __init
125bad_addr(unsigned long *addrp, unsigned long size, unsigned long align)
126{
127 int i;
128 unsigned long addr = *addrp, last;
129 int changed = 0;
130again:
131 last = addr + size;
132 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
133 struct early_res *r = &early_res[i];
134 if (last >= r->start && addr < r->end) {
135 *addrp = addr = round_up(r->end, align);
136 changed = 1;
137 goto again;
138 }
139 }
140 return changed;
141}
142
143/* Check for already reserved areas */
144static inline int __init
145bad_addr_size(unsigned long *addrp, unsigned long *sizep, unsigned long align)
146{
147 int i;
148 unsigned long addr = *addrp, last;
149 unsigned long size = *sizep;
150 int changed = 0;
151again:
152 last = addr + size;
153 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
154 struct early_res *r = &early_res[i];
155 if (last > r->start && addr < r->start) {
156 size = r->start - addr;
157 changed = 1;
158 goto again;
159 }
160 if (last > r->end && addr < r->end) {
161 addr = round_up(r->end, align);
162 size = last - addr;
163 changed = 1;
164 goto again;
165 }
166 if (last <= r->end && addr >= r->start) {
167 (*sizep)++;
168 return 0;
169 }
170 }
171 if (changed) {
172 *addrp = addr;
173 *sizep = size;
174 }
175 return changed;
176}
177
178/*
179 * Find a free area with specified alignment in a specific range.
180 */
181unsigned long __init find_e820_area(unsigned long start, unsigned long end,
182 unsigned long size, unsigned long align)
183{
184 int i;
185
186 for (i = 0; i < e820.nr_map; i++) {
187 struct e820entry *ei = &e820.map[i];
188 unsigned long addr, last;
189 unsigned long ei_last;
190
191 if (ei->type != E820_RAM)
192 continue;
193 addr = round_up(ei->addr, align);
194 ei_last = ei->addr + ei->size;
195 if (addr < start)
196 addr = round_up(start, align);
197 if (addr >= ei_last)
198 continue;
199 while (bad_addr(&addr, size, align) && addr+size <= ei_last)
200 ;
201 last = addr + size;
202 if (last > ei_last)
203 continue;
204 if (last > end)
205 continue;
206 return addr;
207 }
208 return -1UL;
209}
210
211/*
212 * Find next free range after *start
213 */
214unsigned long __init find_e820_area_size(unsigned long start,
215 unsigned long *sizep,
216 unsigned long align)
217{
218 int i;
219
220 for (i = 0; i < e820.nr_map; i++) {
221 struct e820entry *ei = &e820.map[i];
222 unsigned long addr, last;
223 unsigned long ei_last;
224
225 if (ei->type != E820_RAM)
226 continue;
227 addr = round_up(ei->addr, align);
228 ei_last = ei->addr + ei->size;
229 if (addr < start)
230 addr = round_up(start, align);
231 if (addr >= ei_last)
232 continue;
233 *sizep = ei_last - addr;
234 while (bad_addr_size(&addr, sizep, align) &&
235 addr + *sizep <= ei_last)
236 ;
237 last = addr + *sizep;
238 if (last > ei_last)
239 continue;
240 return addr;
241 }
242 return -1UL;
243
244}
245/*
246 * Find the highest page frame number we have available 50 * Find the highest page frame number we have available
247 */ 51 */
248unsigned long __init e820_end_of_ram(void) 52unsigned long __init e820_end_of_ram(void)