diff options
-rw-r--r-- | arch/sh/kernel/setup.c | 78 |
1 files changed, 58 insertions, 20 deletions
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 14735d5ede52..9c7f7811af70 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c | |||
@@ -188,6 +188,63 @@ static inline void __init reserve_crashkernel(void) | |||
188 | {} | 188 | {} |
189 | #endif | 189 | #endif |
190 | 190 | ||
191 | static void __init check_for_initrd(void) | ||
192 | { | ||
193 | #ifdef CONFIG_BLK_DEV_INITRD | ||
194 | unsigned long start, end; | ||
195 | |||
196 | /* | ||
197 | * Check for the rare cases where boot loaders adhere to the boot | ||
198 | * ABI. | ||
199 | */ | ||
200 | if (!LOADER_TYPE || !INITRD_START || !INITRD_SIZE) | ||
201 | goto disable; | ||
202 | |||
203 | start = INITRD_START + __MEMORY_START; | ||
204 | end = start + INITRD_SIZE; | ||
205 | |||
206 | if (unlikely(end <= start)) | ||
207 | goto disable; | ||
208 | if (unlikely(start & ~PAGE_MASK)) { | ||
209 | pr_err("initrd must be page aligned\n"); | ||
210 | goto disable; | ||
211 | } | ||
212 | |||
213 | if (unlikely(start < PAGE_OFFSET)) { | ||
214 | pr_err("initrd start < PAGE_OFFSET\n"); | ||
215 | goto disable; | ||
216 | } | ||
217 | |||
218 | if (unlikely(end > lmb_end_of_DRAM())) { | ||
219 | pr_err("initrd extends beyond end of memory " | ||
220 | "(0x%08lx > 0x%08lx)\ndisabling initrd\n", | ||
221 | end, (unsigned long)lmb_end_of_DRAM()); | ||
222 | goto disable; | ||
223 | } | ||
224 | |||
225 | /* | ||
226 | * If we got this far inspite of the boot loader's best efforts | ||
227 | * to the contrary, assume we actually have a valid initrd and | ||
228 | * fix up the root dev. | ||
229 | */ | ||
230 | ROOT_DEV = Root_RAM0; | ||
231 | |||
232 | /* | ||
233 | * Address sanitization | ||
234 | */ | ||
235 | initrd_start = (unsigned long)__va(__pa(start)); | ||
236 | initrd_end = initrd_start + INITRD_SIZE; | ||
237 | |||
238 | reserve_bootmem(__pa(initrd_start), INITRD_SIZE, BOOTMEM_DEFAULT); | ||
239 | |||
240 | return; | ||
241 | |||
242 | disable: | ||
243 | pr_info("initrd disabled\n"); | ||
244 | initrd_start = initrd_end = 0; | ||
245 | #endif | ||
246 | } | ||
247 | |||
191 | void __cpuinit calibrate_delay(void) | 248 | void __cpuinit calibrate_delay(void) |
192 | { | 249 | { |
193 | struct clk *clk = clk_get(NULL, "cpu_clk"); | 250 | struct clk *clk = clk_get(NULL, "cpu_clk"); |
@@ -277,26 +334,7 @@ void __init setup_bootmem_allocator(unsigned long free_pfn) | |||
277 | 334 | ||
278 | sparse_memory_present_with_active_regions(0); | 335 | sparse_memory_present_with_active_regions(0); |
279 | 336 | ||
280 | #ifdef CONFIG_BLK_DEV_INITRD | 337 | check_for_initrd(); |
281 | ROOT_DEV = Root_RAM0; | ||
282 | |||
283 | if (LOADER_TYPE && INITRD_START) { | ||
284 | unsigned long initrd_start_phys = INITRD_START + __MEMORY_START; | ||
285 | |||
286 | if (initrd_start_phys + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) { | ||
287 | reserve_bootmem(initrd_start_phys, INITRD_SIZE, | ||
288 | BOOTMEM_DEFAULT); | ||
289 | initrd_start = (unsigned long)__va(initrd_start_phys); | ||
290 | initrd_end = initrd_start + INITRD_SIZE; | ||
291 | } else { | ||
292 | printk("initrd extends beyond end of memory " | ||
293 | "(0x%08lx > 0x%08lx)\ndisabling initrd\n", | ||
294 | initrd_start_phys + INITRD_SIZE, | ||
295 | (unsigned long)PFN_PHYS(max_low_pfn)); | ||
296 | initrd_start = 0; | ||
297 | } | ||
298 | } | ||
299 | #endif | ||
300 | 338 | ||
301 | reserve_crashkernel(); | 339 | reserve_crashkernel(); |
302 | } | 340 | } |