diff options
Diffstat (limited to 'arch/avr32/kernel/setup.c')
-rw-r--r-- | arch/avr32/kernel/setup.c | 484 |
1 files changed, 371 insertions, 113 deletions
diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c index a1a7c3c3f522..b279d66acf5f 100644 --- a/arch/avr32/kernel/setup.c +++ b/arch/avr32/kernel/setup.c | |||
@@ -8,12 +8,14 @@ | |||
8 | 8 | ||
9 | #include <linux/clk.h> | 9 | #include <linux/clk.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/initrd.h> | ||
11 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
12 | #include <linux/console.h> | 13 | #include <linux/console.h> |
13 | #include <linux/ioport.h> | 14 | #include <linux/ioport.h> |
14 | #include <linux/bootmem.h> | 15 | #include <linux/bootmem.h> |
15 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/pfn.h> | ||
17 | #include <linux/root_dev.h> | 19 | #include <linux/root_dev.h> |
18 | #include <linux/cpu.h> | 20 | #include <linux/cpu.h> |
19 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
@@ -30,13 +32,6 @@ | |||
30 | extern int root_mountflags; | 32 | extern int root_mountflags; |
31 | 33 | ||
32 | /* | 34 | /* |
33 | * Bootloader-provided information about physical memory | ||
34 | */ | ||
35 | struct tag_mem_range *mem_phys; | ||
36 | struct tag_mem_range *mem_reserved; | ||
37 | struct tag_mem_range *mem_ramdisk; | ||
38 | |||
39 | /* | ||
40 | * Initialize loops_per_jiffy as 5000000 (500MIPS). | 35 | * Initialize loops_per_jiffy as 5000000 (500MIPS). |
41 | * Better make it too large than too small... | 36 | * Better make it too large than too small... |
42 | */ | 37 | */ |
@@ -48,48 +43,193 @@ EXPORT_SYMBOL(boot_cpu_data); | |||
48 | static char __initdata command_line[COMMAND_LINE_SIZE]; | 43 | static char __initdata command_line[COMMAND_LINE_SIZE]; |
49 | 44 | ||
50 | /* | 45 | /* |
51 | * Should be more than enough, but if you have a _really_ complex | 46 | * Standard memory resources |
52 | * setup, you might need to increase the size of this... | ||
53 | */ | 47 | */ |
54 | static struct tag_mem_range __initdata mem_range_cache[32]; | 48 | static struct resource __initdata kernel_data = { |
55 | static unsigned mem_range_next_free; | 49 | .name = "Kernel data", |
50 | .start = 0, | ||
51 | .end = 0, | ||
52 | .flags = IORESOURCE_MEM, | ||
53 | }; | ||
54 | static struct resource __initdata kernel_code = { | ||
55 | .name = "Kernel code", | ||
56 | .start = 0, | ||
57 | .end = 0, | ||
58 | .flags = IORESOURCE_MEM, | ||
59 | .sibling = &kernel_data, | ||
60 | }; | ||
56 | 61 | ||
57 | /* | 62 | /* |
58 | * Standard memory resources | 63 | * Available system RAM and reserved regions as singly linked |
64 | * lists. These lists are traversed using the sibling pointer in | ||
65 | * struct resource and are kept sorted at all times. | ||
59 | */ | 66 | */ |
60 | static struct resource mem_res[] = { | 67 | static struct resource *__initdata system_ram; |
61 | { | 68 | static struct resource *__initdata reserved = &kernel_code; |
62 | .name = "Kernel code", | 69 | |
63 | .start = 0, | 70 | /* |
64 | .end = 0, | 71 | * We need to allocate these before the bootmem allocator is up and |
65 | .flags = IORESOURCE_MEM | 72 | * running, so we need this "cache". 32 entries are probably enough |
66 | }, | 73 | * for all but the most insanely complex systems. |
67 | { | 74 | */ |
68 | .name = "Kernel data", | 75 | static struct resource __initdata res_cache[32]; |
69 | .start = 0, | 76 | static unsigned int __initdata res_cache_next_free; |
70 | .end = 0, | 77 | |
71 | .flags = IORESOURCE_MEM, | 78 | static void __init resource_init(void) |
72 | }, | 79 | { |
73 | }; | 80 | struct resource *mem, *res; |
81 | struct resource *new; | ||
82 | |||
83 | kernel_code.start = __pa(init_mm.start_code); | ||
84 | |||
85 | for (mem = system_ram; mem; mem = mem->sibling) { | ||
86 | new = alloc_bootmem_low(sizeof(struct resource)); | ||
87 | memcpy(new, mem, sizeof(struct resource)); | ||
88 | |||
89 | new->sibling = NULL; | ||
90 | if (request_resource(&iomem_resource, new)) | ||
91 | printk(KERN_WARNING "Bad RAM resource %08x-%08x\n", | ||
92 | mem->start, mem->end); | ||
93 | } | ||
94 | |||
95 | for (res = reserved; res; res = res->sibling) { | ||
96 | new = alloc_bootmem_low(sizeof(struct resource)); | ||
97 | memcpy(new, res, sizeof(struct resource)); | ||
98 | |||
99 | new->sibling = NULL; | ||
100 | if (insert_resource(&iomem_resource, new)) | ||
101 | printk(KERN_WARNING | ||
102 | "Bad reserved resource %s (%08x-%08x)\n", | ||
103 | res->name, res->start, res->end); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | static void __init | ||
108 | add_physical_memory(resource_size_t start, resource_size_t end) | ||
109 | { | ||
110 | struct resource *new, *next, **pprev; | ||
111 | |||
112 | for (pprev = &system_ram, next = system_ram; next; | ||
113 | pprev = &next->sibling, next = next->sibling) { | ||
114 | if (end < next->start) | ||
115 | break; | ||
116 | if (start <= next->end) { | ||
117 | printk(KERN_WARNING | ||
118 | "Warning: Physical memory map is broken\n"); | ||
119 | printk(KERN_WARNING | ||
120 | "Warning: %08x-%08x overlaps %08x-%08x\n", | ||
121 | start, end, next->start, next->end); | ||
122 | return; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | if (res_cache_next_free >= ARRAY_SIZE(res_cache)) { | ||
127 | printk(KERN_WARNING | ||
128 | "Warning: Failed to add physical memory %08x-%08x\n", | ||
129 | start, end); | ||
130 | return; | ||
131 | } | ||
132 | |||
133 | new = &res_cache[res_cache_next_free++]; | ||
134 | new->start = start; | ||
135 | new->end = end; | ||
136 | new->name = "System RAM"; | ||
137 | new->flags = IORESOURCE_MEM; | ||
138 | |||
139 | *pprev = new; | ||
140 | } | ||
141 | |||
142 | static int __init | ||
143 | add_reserved_region(resource_size_t start, resource_size_t end, | ||
144 | const char *name) | ||
145 | { | ||
146 | struct resource *new, *next, **pprev; | ||
147 | |||
148 | if (end < start) | ||
149 | return -EINVAL; | ||
150 | |||
151 | if (res_cache_next_free >= ARRAY_SIZE(res_cache)) | ||
152 | return -ENOMEM; | ||
153 | |||
154 | for (pprev = &reserved, next = reserved; next; | ||
155 | pprev = &next->sibling, next = next->sibling) { | ||
156 | if (end < next->start) | ||
157 | break; | ||
158 | if (start <= next->end) | ||
159 | return -EBUSY; | ||
160 | } | ||
161 | |||
162 | new = &res_cache[res_cache_next_free++]; | ||
163 | new->start = start; | ||
164 | new->end = end; | ||
165 | new->name = name; | ||
166 | new->flags = IORESOURCE_MEM; | ||
167 | |||
168 | *pprev = new; | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static unsigned long __init | ||
174 | find_free_region(const struct resource *mem, resource_size_t size, | ||
175 | resource_size_t align) | ||
176 | { | ||
177 | struct resource *res; | ||
178 | unsigned long target; | ||
179 | |||
180 | target = ALIGN(mem->start, align); | ||
181 | for (res = reserved; res; res = res->sibling) { | ||
182 | if ((target + size) <= res->start) | ||
183 | break; | ||
184 | if (target <= res->end) | ||
185 | target = ALIGN(res->end + 1, align); | ||
186 | } | ||
187 | |||
188 | if ((target + size) > (mem->end + 1)) | ||
189 | return mem->end + 1; | ||
190 | |||
191 | return target; | ||
192 | } | ||
193 | |||
194 | static int __init | ||
195 | alloc_reserved_region(resource_size_t *start, resource_size_t size, | ||
196 | resource_size_t align, const char *name) | ||
197 | { | ||
198 | struct resource *mem; | ||
199 | resource_size_t target; | ||
200 | int ret; | ||
201 | |||
202 | for (mem = system_ram; mem; mem = mem->sibling) { | ||
203 | target = find_free_region(mem, size, align); | ||
204 | if (target <= mem->end) { | ||
205 | ret = add_reserved_region(target, target + size - 1, | ||
206 | name); | ||
207 | if (!ret) | ||
208 | *start = target; | ||
209 | return ret; | ||
210 | } | ||
211 | } | ||
74 | 212 | ||
75 | #define kernel_code mem_res[0] | 213 | return -ENOMEM; |
76 | #define kernel_data mem_res[1] | 214 | } |
77 | 215 | ||
78 | /* | 216 | /* |
79 | * Early framebuffer allocation. Works as follows: | 217 | * Early framebuffer allocation. Works as follows: |
80 | * - If fbmem_size is zero, nothing will be allocated or reserved. | 218 | * - If fbmem_size is zero, nothing will be allocated or reserved. |
81 | * - If fbmem_start is zero when setup_bootmem() is called, | 219 | * - If fbmem_start is zero when setup_bootmem() is called, |
82 | * fbmem_size bytes will be allocated from the bootmem allocator. | 220 | * a block of fbmem_size bytes will be reserved before bootmem |
221 | * initialization. It will be aligned to the largest page size | ||
222 | * that fbmem_size is a multiple of. | ||
83 | * - If fbmem_start is nonzero, an area of size fbmem_size will be | 223 | * - If fbmem_start is nonzero, an area of size fbmem_size will be |
84 | * reserved at the physical address fbmem_start if necessary. If | 224 | * reserved at the physical address fbmem_start if possible. If |
85 | * the area isn't in a memory region known to the kernel, it will | 225 | * it collides with other reserved memory, a different block of |
86 | * be left alone. | 226 | * same size will be allocated, just as if fbmem_start was zero. |
87 | * | 227 | * |
88 | * Board-specific code may use these variables to set up platform data | 228 | * Board-specific code may use these variables to set up platform data |
89 | * for the framebuffer driver if fbmem_size is nonzero. | 229 | * for the framebuffer driver if fbmem_size is nonzero. |
90 | */ | 230 | */ |
91 | static unsigned long __initdata fbmem_start; | 231 | resource_size_t __initdata fbmem_start; |
92 | static unsigned long __initdata fbmem_size; | 232 | resource_size_t __initdata fbmem_size; |
93 | 233 | ||
94 | /* | 234 | /* |
95 | * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for | 235 | * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for |
@@ -103,48 +243,42 @@ static unsigned long __initdata fbmem_size; | |||
103 | */ | 243 | */ |
104 | static int __init early_parse_fbmem(char *p) | 244 | static int __init early_parse_fbmem(char *p) |
105 | { | 245 | { |
246 | int ret; | ||
247 | unsigned long align; | ||
248 | |||
106 | fbmem_size = memparse(p, &p); | 249 | fbmem_size = memparse(p, &p); |
107 | if (*p == '@') | 250 | if (*p == '@') { |
108 | fbmem_start = memparse(p, &p); | 251 | fbmem_start = memparse(p, &p); |
109 | return 0; | 252 | ret = add_reserved_region(fbmem_start, |
110 | } | 253 | fbmem_start + fbmem_size - 1, |
111 | early_param("fbmem", early_parse_fbmem); | 254 | "Framebuffer"); |
112 | 255 | if (ret) { | |
113 | static inline void __init resource_init(void) | 256 | printk(KERN_WARNING |
114 | { | 257 | "Failed to reserve framebuffer memory\n"); |
115 | struct tag_mem_range *region; | 258 | fbmem_start = 0; |
116 | 259 | } | |
117 | kernel_code.start = __pa(init_mm.start_code); | 260 | } |
118 | kernel_code.end = __pa(init_mm.end_code - 1); | ||
119 | kernel_data.start = __pa(init_mm.end_code); | ||
120 | kernel_data.end = __pa(init_mm.brk - 1); | ||
121 | |||
122 | for (region = mem_phys; region; region = region->next) { | ||
123 | struct resource *res; | ||
124 | unsigned long phys_start, phys_end; | ||
125 | |||
126 | if (region->size == 0) | ||
127 | continue; | ||
128 | |||
129 | phys_start = region->addr; | ||
130 | phys_end = phys_start + region->size - 1; | ||
131 | |||
132 | res = alloc_bootmem_low(sizeof(*res)); | ||
133 | res->name = "System RAM"; | ||
134 | res->start = phys_start; | ||
135 | res->end = phys_end; | ||
136 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
137 | |||
138 | request_resource (&iomem_resource, res); | ||
139 | 261 | ||
140 | if (kernel_code.start >= res->start && | 262 | if (!fbmem_start) { |
141 | kernel_code.end <= res->end) | 263 | if ((fbmem_size & 0x000fffffUL) == 0) |
142 | request_resource (res, &kernel_code); | 264 | align = 0x100000; /* 1 MiB */ |
143 | if (kernel_data.start >= res->start && | 265 | else if ((fbmem_size & 0x0000ffffUL) == 0) |
144 | kernel_data.end <= res->end) | 266 | align = 0x10000; /* 64 KiB */ |
145 | request_resource (res, &kernel_data); | 267 | else |
268 | align = 0x1000; /* 4 KiB */ | ||
269 | |||
270 | ret = alloc_reserved_region(&fbmem_start, fbmem_size, | ||
271 | align, "Framebuffer"); | ||
272 | if (ret) { | ||
273 | printk(KERN_WARNING | ||
274 | "Failed to allocate framebuffer memory\n"); | ||
275 | fbmem_size = 0; | ||
276 | } | ||
146 | } | 277 | } |
278 | |||
279 | return 0; | ||
147 | } | 280 | } |
281 | early_param("fbmem", early_parse_fbmem); | ||
148 | 282 | ||
149 | static int __init parse_tag_core(struct tag *tag) | 283 | static int __init parse_tag_core(struct tag *tag) |
150 | { | 284 | { |
@@ -157,11 +291,9 @@ static int __init parse_tag_core(struct tag *tag) | |||
157 | } | 291 | } |
158 | __tagtable(ATAG_CORE, parse_tag_core); | 292 | __tagtable(ATAG_CORE, parse_tag_core); |
159 | 293 | ||
160 | static int __init parse_tag_mem_range(struct tag *tag, | 294 | static int __init parse_tag_mem(struct tag *tag) |
161 | struct tag_mem_range **root) | ||
162 | { | 295 | { |
163 | struct tag_mem_range *cur, **pprev; | 296 | unsigned long start, end; |
164 | struct tag_mem_range *new; | ||
165 | 297 | ||
166 | /* | 298 | /* |
167 | * Ignore zero-sized entries. If we're running standalone, the | 299 | * Ignore zero-sized entries. If we're running standalone, the |
@@ -171,34 +303,53 @@ static int __init parse_tag_mem_range(struct tag *tag, | |||
171 | if (tag->u.mem_range.size == 0) | 303 | if (tag->u.mem_range.size == 0) |
172 | return 0; | 304 | return 0; |
173 | 305 | ||
174 | /* | 306 | start = tag->u.mem_range.addr; |
175 | * Copy the data so the bootmem init code doesn't need to care | 307 | end = tag->u.mem_range.addr + tag->u.mem_range.size - 1; |
176 | * about it. | 308 | |
177 | */ | 309 | add_physical_memory(start, end); |
178 | if (mem_range_next_free >= ARRAY_SIZE(mem_range_cache)) | 310 | return 0; |
179 | panic("Physical memory map too complex!\n"); | 311 | } |
312 | __tagtable(ATAG_MEM, parse_tag_mem); | ||
313 | |||
314 | static int __init parse_tag_rdimg(struct tag *tag) | ||
315 | { | ||
316 | #ifdef CONFIG_INITRD | ||
317 | struct tag_mem_range *mem = &tag->u.mem_range; | ||
318 | int ret; | ||
180 | 319 | ||
181 | new = &mem_range_cache[mem_range_next_free++]; | 320 | if (initrd_start) { |
182 | *new = tag->u.mem_range; | 321 | printk(KERN_WARNING |
322 | "Warning: Only the first initrd image will be used\n"); | ||
323 | return 0; | ||
324 | } | ||
183 | 325 | ||
184 | pprev = root; | 326 | ret = add_reserved_region(mem->start, mem->start + mem->size - 1, |
185 | cur = *root; | 327 | "initrd"); |
186 | while (cur) { | 328 | if (ret) { |
187 | pprev = &cur->next; | 329 | printk(KERN_WARNING |
188 | cur = cur->next; | 330 | "Warning: Failed to reserve initrd memory\n"); |
331 | return ret; | ||
189 | } | 332 | } |
190 | 333 | ||
191 | *pprev = new; | 334 | initrd_start = (unsigned long)__va(mem->addr); |
192 | new->next = NULL; | 335 | initrd_end = initrd_start + mem->size; |
336 | #else | ||
337 | printk(KERN_WARNING "RAM disk image present, but " | ||
338 | "no initrd support in kernel, ignoring\n"); | ||
339 | #endif | ||
193 | 340 | ||
194 | return 0; | 341 | return 0; |
195 | } | 342 | } |
343 | __tagtable(ATAG_RDIMG, parse_tag_rdimg); | ||
196 | 344 | ||
197 | static int __init parse_tag_mem(struct tag *tag) | 345 | static int __init parse_tag_rsvd_mem(struct tag *tag) |
198 | { | 346 | { |
199 | return parse_tag_mem_range(tag, &mem_phys); | 347 | struct tag_mem_range *mem = &tag->u.mem_range; |
348 | |||
349 | return add_reserved_region(mem->addr, mem->addr + mem->size - 1, | ||
350 | "Reserved"); | ||
200 | } | 351 | } |
201 | __tagtable(ATAG_MEM, parse_tag_mem); | 352 | __tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem); |
202 | 353 | ||
203 | static int __init parse_tag_cmdline(struct tag *tag) | 354 | static int __init parse_tag_cmdline(struct tag *tag) |
204 | { | 355 | { |
@@ -207,12 +358,6 @@ static int __init parse_tag_cmdline(struct tag *tag) | |||
207 | } | 358 | } |
208 | __tagtable(ATAG_CMDLINE, parse_tag_cmdline); | 359 | __tagtable(ATAG_CMDLINE, parse_tag_cmdline); |
209 | 360 | ||
210 | static int __init parse_tag_rdimg(struct tag *tag) | ||
211 | { | ||
212 | return parse_tag_mem_range(tag, &mem_ramdisk); | ||
213 | } | ||
214 | __tagtable(ATAG_RDIMG, parse_tag_rdimg); | ||
215 | |||
216 | static int __init parse_tag_clock(struct tag *tag) | 361 | static int __init parse_tag_clock(struct tag *tag) |
217 | { | 362 | { |
218 | /* | 363 | /* |
@@ -223,12 +368,6 @@ static int __init parse_tag_clock(struct tag *tag) | |||
223 | } | 368 | } |
224 | __tagtable(ATAG_CLOCK, parse_tag_clock); | 369 | __tagtable(ATAG_CLOCK, parse_tag_clock); |
225 | 370 | ||
226 | static int __init parse_tag_rsvd_mem(struct tag *tag) | ||
227 | { | ||
228 | return parse_tag_mem_range(tag, &mem_reserved); | ||
229 | } | ||
230 | __tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem); | ||
231 | |||
232 | /* | 371 | /* |
233 | * Scan the tag table for this tag, and call its parse function. The | 372 | * Scan the tag table for this tag, and call its parse function. The |
234 | * tag table is built by the linker from all the __tagtable | 373 | * tag table is built by the linker from all the __tagtable |
@@ -260,10 +399,137 @@ static void __init parse_tags(struct tag *t) | |||
260 | t->hdr.tag); | 399 | t->hdr.tag); |
261 | } | 400 | } |
262 | 401 | ||
402 | /* | ||
403 | * Find a free memory region large enough for storing the | ||
404 | * bootmem bitmap. | ||
405 | */ | ||
406 | static unsigned long __init | ||
407 | find_bootmap_pfn(const struct resource *mem) | ||
408 | { | ||
409 | unsigned long bootmap_pages, bootmap_len; | ||
410 | unsigned long node_pages = PFN_UP(mem->end - mem->start + 1); | ||
411 | unsigned long bootmap_start; | ||
412 | |||
413 | bootmap_pages = bootmem_bootmap_pages(node_pages); | ||
414 | bootmap_len = bootmap_pages << PAGE_SHIFT; | ||
415 | |||
416 | /* | ||
417 | * Find a large enough region without reserved pages for | ||
418 | * storing the bootmem bitmap. We can take advantage of the | ||
419 | * fact that all lists have been sorted. | ||
420 | * | ||
421 | * We have to check that we don't collide with any reserved | ||
422 | * regions, which includes the kernel image and any RAMDISK | ||
423 | * images. | ||
424 | */ | ||
425 | bootmap_start = find_free_region(mem, bootmap_len, PAGE_SIZE); | ||
426 | |||
427 | return bootmap_start >> PAGE_SHIFT; | ||
428 | } | ||
429 | |||
430 | #define MAX_LOWMEM HIGHMEM_START | ||
431 | #define MAX_LOWMEM_PFN PFN_DOWN(MAX_LOWMEM) | ||
432 | |||
433 | static void __init setup_bootmem(void) | ||
434 | { | ||
435 | unsigned bootmap_size; | ||
436 | unsigned long first_pfn, bootmap_pfn, pages; | ||
437 | unsigned long max_pfn, max_low_pfn; | ||
438 | unsigned node = 0; | ||
439 | struct resource *res; | ||
440 | |||
441 | printk(KERN_INFO "Physical memory:\n"); | ||
442 | for (res = system_ram; res; res = res->sibling) | ||
443 | printk(" %08x-%08x\n", res->start, res->end); | ||
444 | printk(KERN_INFO "Reserved memory:\n"); | ||
445 | for (res = reserved; res; res = res->sibling) | ||
446 | printk(" %08x-%08x: %s\n", | ||
447 | res->start, res->end, res->name); | ||
448 | |||
449 | nodes_clear(node_online_map); | ||
450 | |||
451 | if (system_ram->sibling) | ||
452 | printk(KERN_WARNING "Only using first memory bank\n"); | ||
453 | |||
454 | for (res = system_ram; res; res = NULL) { | ||
455 | first_pfn = PFN_UP(res->start); | ||
456 | max_low_pfn = max_pfn = PFN_DOWN(res->end + 1); | ||
457 | bootmap_pfn = find_bootmap_pfn(res); | ||
458 | if (bootmap_pfn > max_pfn) | ||
459 | panic("No space for bootmem bitmap!\n"); | ||
460 | |||
461 | if (max_low_pfn > MAX_LOWMEM_PFN) { | ||
462 | max_low_pfn = MAX_LOWMEM_PFN; | ||
463 | #ifndef CONFIG_HIGHMEM | ||
464 | /* | ||
465 | * Lowmem is memory that can be addressed | ||
466 | * directly through P1/P2 | ||
467 | */ | ||
468 | printk(KERN_WARNING | ||
469 | "Node %u: Only %ld MiB of memory will be used.\n", | ||
470 | node, MAX_LOWMEM >> 20); | ||
471 | printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n"); | ||
472 | #else | ||
473 | #error HIGHMEM is not supported by AVR32 yet | ||
474 | #endif | ||
475 | } | ||
476 | |||
477 | /* Initialize the boot-time allocator with low memory only. */ | ||
478 | bootmap_size = init_bootmem_node(NODE_DATA(node), bootmap_pfn, | ||
479 | first_pfn, max_low_pfn); | ||
480 | |||
481 | /* | ||
482 | * Register fully available RAM pages with the bootmem | ||
483 | * allocator. | ||
484 | */ | ||
485 | pages = max_low_pfn - first_pfn; | ||
486 | free_bootmem_node (NODE_DATA(node), PFN_PHYS(first_pfn), | ||
487 | PFN_PHYS(pages)); | ||
488 | |||
489 | /* Reserve space for the bootmem bitmap... */ | ||
490 | reserve_bootmem_node(NODE_DATA(node), | ||
491 | PFN_PHYS(bootmap_pfn), | ||
492 | bootmap_size); | ||
493 | |||
494 | /* ...and any other reserved regions. */ | ||
495 | for (res = reserved; res; res = res->sibling) { | ||
496 | if (res->start > PFN_PHYS(max_pfn)) | ||
497 | break; | ||
498 | |||
499 | /* | ||
500 | * resource_init will complain about partial | ||
501 | * overlaps, so we'll just ignore such | ||
502 | * resources for now. | ||
503 | */ | ||
504 | if (res->start >= PFN_PHYS(first_pfn) | ||
505 | && res->end < PFN_PHYS(max_pfn)) | ||
506 | reserve_bootmem_node( | ||
507 | NODE_DATA(node), res->start, | ||
508 | res->end - res->start + 1); | ||
509 | } | ||
510 | |||
511 | node_set_online(node); | ||
512 | } | ||
513 | } | ||
514 | |||
263 | void __init setup_arch (char **cmdline_p) | 515 | void __init setup_arch (char **cmdline_p) |
264 | { | 516 | { |
265 | struct clk *cpu_clk; | 517 | struct clk *cpu_clk; |
266 | 518 | ||
519 | init_mm.start_code = (unsigned long)_text; | ||
520 | init_mm.end_code = (unsigned long)_etext; | ||
521 | init_mm.end_data = (unsigned long)_edata; | ||
522 | init_mm.brk = (unsigned long)_end; | ||
523 | |||
524 | /* | ||
525 | * Include .init section to make allocations easier. It will | ||
526 | * be removed before the resource is actually requested. | ||
527 | */ | ||
528 | kernel_code.start = __pa(__init_begin); | ||
529 | kernel_code.end = __pa(init_mm.end_code - 1); | ||
530 | kernel_data.start = __pa(init_mm.end_code); | ||
531 | kernel_data.end = __pa(init_mm.brk - 1); | ||
532 | |||
267 | parse_tags(bootloader_tags); | 533 | parse_tags(bootloader_tags); |
268 | 534 | ||
269 | setup_processor(); | 535 | setup_processor(); |
@@ -289,24 +555,16 @@ void __init setup_arch (char **cmdline_p) | |||
289 | ((cpu_hz + 500) / 1000) % 1000); | 555 | ((cpu_hz + 500) / 1000) % 1000); |
290 | } | 556 | } |
291 | 557 | ||
292 | init_mm.start_code = (unsigned long) &_text; | ||
293 | init_mm.end_code = (unsigned long) &_etext; | ||
294 | init_mm.end_data = (unsigned long) &_edata; | ||
295 | init_mm.brk = (unsigned long) &_end; | ||
296 | |||
297 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); | 558 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); |
298 | *cmdline_p = command_line; | 559 | *cmdline_p = command_line; |
299 | parse_early_param(); | 560 | parse_early_param(); |
300 | 561 | ||
301 | setup_bootmem(); | 562 | setup_bootmem(); |
302 | 563 | ||
303 | board_setup_fbmem(fbmem_start, fbmem_size); | ||
304 | |||
305 | #ifdef CONFIG_VT | 564 | #ifdef CONFIG_VT |
306 | conswitchp = &dummy_con; | 565 | conswitchp = &dummy_con; |
307 | #endif | 566 | #endif |
308 | 567 | ||
309 | paging_init(); | 568 | paging_init(); |
310 | |||
311 | resource_init(); | 569 | resource_init(); |
312 | } | 570 | } |