diff options
Diffstat (limited to 'arch/x86/kernel/e820_64.c')
-rw-r--r-- | arch/x86/kernel/e820_64.c | 196 |
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; | |||
47 | static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT; | 47 | static 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 | |||
54 | struct early_res { | ||
55 | unsigned long start, end; | ||
56 | char name[16]; | ||
57 | }; | ||
58 | static 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 | |||
66 | void __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 | |||
85 | void __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 | |||
107 | void __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 */ | ||
124 | static inline int __init | ||
125 | bad_addr(unsigned long *addrp, unsigned long size, unsigned long align) | ||
126 | { | ||
127 | int i; | ||
128 | unsigned long addr = *addrp, last; | ||
129 | int changed = 0; | ||
130 | again: | ||
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 */ | ||
144 | static inline int __init | ||
145 | bad_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; | ||
151 | again: | ||
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 | */ | ||
181 | unsigned 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 | */ | ||
214 | unsigned 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 | */ |
248 | unsigned long __init e820_end_of_ram(void) | 52 | unsigned long __init e820_end_of_ram(void) |