2 * Copyright (C) 2004-2006 Atmel Corporation
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
10 #include <linux/init.h>
11 #include <linux/initrd.h>
12 #include <linux/sched.h>
13 #include <linux/console.h>
14 #include <linux/ioport.h>
15 #include <linux/bootmem.h>
17 #include <linux/module.h>
18 #include <linux/pfn.h>
19 #include <linux/root_dev.h>
20 #include <linux/cpu.h>
21 #include <linux/kernel.h>
23 #include <asm/sections.h>
24 #include <asm/processor.h>
25 #include <asm/pgtable.h>
26 #include <asm/setup.h>
27 #include <asm/sysreg.h>
29 #include <asm/arch/board.h>
30 #include <asm/arch/init.h>
32 extern int root_mountflags;
35 * Bootloader-provided information about physical memory
37 struct tag_mem_range *mem_phys;
38 struct tag_mem_range *mem_reserved;
39 struct tag_mem_range *mem_ramdisk;
42 * Initialize loops_per_jiffy as 5000000 (500MIPS).
43 * Better make it too large than too small...
45 struct avr32_cpuinfo boot_cpu_data = {
46 .loops_per_jiffy = 5000000
48 EXPORT_SYMBOL(boot_cpu_data);
50 static char __initdata command_line[COMMAND_LINE_SIZE];
53 * Should be more than enough, but if you have a _really_ complex
54 * setup, you might need to increase the size of this...
56 static struct tag_mem_range __initdata mem_range_cache[32];
57 static unsigned mem_range_next_free;
60 * Standard memory resources
62 static struct resource mem_res[] = {
64 .name = "Kernel code",
67 .flags = IORESOURCE_MEM
70 .name = "Kernel data",
73 .flags = IORESOURCE_MEM,
77 #define kernel_code mem_res[0]
78 #define kernel_data mem_res[1]
81 * Early framebuffer allocation. Works as follows:
82 * - If fbmem_size is zero, nothing will be allocated or reserved.
83 * - If fbmem_start is zero when setup_bootmem() is called,
84 * fbmem_size bytes will be allocated from the bootmem allocator.
85 * - If fbmem_start is nonzero, an area of size fbmem_size will be
86 * reserved at the physical address fbmem_start if necessary. If
87 * the area isn't in a memory region known to the kernel, it will
90 * Board-specific code may use these variables to set up platform data
91 * for the framebuffer driver if fbmem_size is nonzero.
93 static unsigned long __initdata fbmem_start;
94 static unsigned long __initdata fbmem_size;
97 * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for
100 * "fbmem=xxx[kKmM]@yyy[kKmM]" defines a memory region of size xxx and
101 * starting at yyy to be reserved for use as framebuffer.
103 * The kernel won't verify that the memory region starting at yyy
104 * actually contains usable RAM.
106 static int __init early_parse_fbmem(char *p)
108 fbmem_size = memparse(p, &p);
110 fbmem_start = memparse(p, &p);
113 early_param("fbmem", early_parse_fbmem);
115 static inline void __init resource_init(void)
117 struct tag_mem_range *region;
119 kernel_code.start = __pa(init_mm.start_code);
120 kernel_code.end = __pa(init_mm.end_code - 1);
121 kernel_data.start = __pa(init_mm.end_code);
122 kernel_data.end = __pa(init_mm.brk - 1);
124 for (region = mem_phys; region; region = region->next) {
125 struct resource *res;
126 unsigned long phys_start, phys_end;
128 if (region->size == 0)
131 phys_start = region->addr;
132 phys_end = phys_start + region->size - 1;
134 res = alloc_bootmem_low(sizeof(*res));
135 res->name = "System RAM";
136 res->start = phys_start;
138 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
140 request_resource (&iomem_resource, res);
142 if (kernel_code.start >= res->start &&
143 kernel_code.end <= res->end)
144 request_resource (res, &kernel_code);
145 if (kernel_data.start >= res->start &&
146 kernel_data.end <= res->end)
147 request_resource (res, &kernel_data);
151 static int __init parse_tag_core(struct tag *tag)
153 if (tag->hdr.size > 2) {
154 if ((tag->u.core.flags & 1) == 0)
155 root_mountflags &= ~MS_RDONLY;
156 ROOT_DEV = new_decode_dev(tag->u.core.rootdev);
160 __tagtable(ATAG_CORE, parse_tag_core);
162 static int __init parse_tag_mem_range(struct tag *tag,
163 struct tag_mem_range **root)
165 struct tag_mem_range *cur, **pprev;
166 struct tag_mem_range *new;
169 * Ignore zero-sized entries. If we're running standalone, the
170 * SDRAM code may emit such entries if something goes
173 if (tag->u.mem_range.size == 0)
177 * Copy the data so the bootmem init code doesn't need to care
180 if (mem_range_next_free >= ARRAY_SIZE(mem_range_cache))
181 panic("Physical memory map too complex!\n");
183 new = &mem_range_cache[mem_range_next_free++];
184 *new = tag->u.mem_range;
199 static int __init parse_tag_mem(struct tag *tag)
201 return parse_tag_mem_range(tag, &mem_phys);
203 __tagtable(ATAG_MEM, parse_tag_mem);
205 static int __init parse_tag_cmdline(struct tag *tag)
207 strlcpy(boot_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
210 __tagtable(ATAG_CMDLINE, parse_tag_cmdline);
212 static int __init parse_tag_rdimg(struct tag *tag)
214 return parse_tag_mem_range(tag, &mem_ramdisk);
216 __tagtable(ATAG_RDIMG, parse_tag_rdimg);
218 static int __init parse_tag_clock(struct tag *tag)
221 * We'll figure out the clocks by peeking at the system
222 * manager regs directly.
226 __tagtable(ATAG_CLOCK, parse_tag_clock);
228 static int __init parse_tag_rsvd_mem(struct tag *tag)
230 return parse_tag_mem_range(tag, &mem_reserved);
232 __tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem);
235 * Scan the tag table for this tag, and call its parse function. The
236 * tag table is built by the linker from all the __tagtable
239 static int __init parse_tag(struct tag *tag)
241 extern struct tagtable __tagtable_begin, __tagtable_end;
244 for (t = &__tagtable_begin; t < &__tagtable_end; t++)
245 if (tag->hdr.tag == t->tag) {
250 return t < &__tagtable_end;
254 * Parse all tags in the list we got from the boot loader
256 static void __init parse_tags(struct tag *t)
258 for (; t->hdr.tag != ATAG_NONE; t = tag_next(t))
261 "Ignoring unrecognised tag 0x%08x\n",
265 static void __init print_memory_map(const char *what,
266 struct tag_mem_range *mem)
268 printk ("%s:\n", what);
269 for (; mem; mem = mem->next) {
270 printk (" %08lx - %08lx\n",
271 (unsigned long)mem->addr,
272 (unsigned long)(mem->addr + mem->size));
276 #define MAX_LOWMEM HIGHMEM_START
277 #define MAX_LOWMEM_PFN PFN_DOWN(MAX_LOWMEM)
280 * Sort a list of memory regions in-place by ascending address.
282 * We're using bubble sort because we only have singly linked lists
285 static void __init sort_mem_list(struct tag_mem_range **pmem)
288 struct tag_mem_range **a, **b;
295 a = pmem, b = &(*pmem)->next;
297 if ((*a)->addr > (*b)->addr) {
298 struct tag_mem_range *tmp;
312 * Find a free memory region large enough for storing the
315 static unsigned long __init
316 find_bootmap_pfn(const struct tag_mem_range *mem)
318 unsigned long bootmap_pages, bootmap_len;
319 unsigned long node_pages = PFN_UP(mem->size);
320 unsigned long bootmap_addr = mem->addr;
321 struct tag_mem_range *reserved = mem_reserved;
322 struct tag_mem_range *ramdisk = mem_ramdisk;
323 unsigned long kern_start = __pa(_stext);
324 unsigned long kern_end = __pa(_end);
326 bootmap_pages = bootmem_bootmap_pages(node_pages);
327 bootmap_len = bootmap_pages << PAGE_SHIFT;
330 * Find a large enough region without reserved pages for
331 * storing the bootmem bitmap. We can take advantage of the
332 * fact that all lists have been sorted.
334 * We have to check explicitly reserved regions as well as the
335 * kernel image and any RAMDISK images...
337 * Oh, and we have to make sure we don't overwrite the taglist
338 * since we're going to use it until the bootmem allocator is
339 * fully up and running.
342 if ((bootmap_addr < kern_end) &&
343 ((bootmap_addr + bootmap_len) > kern_start))
344 bootmap_addr = kern_end;
347 (bootmap_addr >= (reserved->addr + reserved->size)))
348 reserved = reserved->next;
351 ((bootmap_addr + bootmap_len) >= reserved->addr)) {
352 bootmap_addr = reserved->addr + reserved->size;
357 (bootmap_addr >= (ramdisk->addr + ramdisk->size)))
358 ramdisk = ramdisk->next;
361 ((bootmap_addr + bootmap_len) < ramdisk->addr))
364 bootmap_addr = ramdisk->addr + ramdisk->size;
367 if ((PFN_UP(bootmap_addr) + bootmap_len) >= (mem->addr + mem->size))
370 return PFN_UP(bootmap_addr);
373 static void __init setup_bootmem(void)
375 unsigned bootmap_size;
376 unsigned long first_pfn, bootmap_pfn, pages;
377 unsigned long max_pfn, max_low_pfn;
378 unsigned long kern_start = __pa(_stext);
379 unsigned long kern_end = __pa(_end);
381 struct tag_mem_range *bank, *res;
383 sort_mem_list(&mem_phys);
384 sort_mem_list(&mem_reserved);
386 print_memory_map("Physical memory", mem_phys);
387 print_memory_map("Reserved memory", mem_reserved);
389 nodes_clear(node_online_map);
392 #ifdef CONFIG_BLK_DEV_INITRD
393 initrd_start = (unsigned long)__va(mem_ramdisk->addr);
394 initrd_end = initrd_start + mem_ramdisk->size;
396 print_memory_map("RAMDISK images", mem_ramdisk);
397 if (mem_ramdisk->next)
399 "Warning: Only the first RAMDISK image "
401 sort_mem_list(&mem_ramdisk);
403 printk(KERN_WARNING "RAM disk image present, but "
404 "no initrd support in kernel!\n");
409 printk(KERN_WARNING "Only using first memory bank\n");
411 for (bank = mem_phys; bank; bank = NULL) {
412 first_pfn = PFN_UP(bank->addr);
413 max_low_pfn = max_pfn = PFN_DOWN(bank->addr + bank->size);
414 bootmap_pfn = find_bootmap_pfn(bank);
415 if (bootmap_pfn > max_pfn)
416 panic("No space for bootmem bitmap!\n");
418 if (max_low_pfn > MAX_LOWMEM_PFN) {
419 max_low_pfn = MAX_LOWMEM_PFN;
420 #ifndef CONFIG_HIGHMEM
422 * Lowmem is memory that can be addressed
423 * directly through P1/P2
426 "Node %u: Only %ld MiB of memory will be used.\n",
427 node, MAX_LOWMEM >> 20);
428 printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
430 #error HIGHMEM is not supported by AVR32 yet
434 /* Initialize the boot-time allocator with low memory only. */
435 bootmap_size = init_bootmem_node(NODE_DATA(node), bootmap_pfn,
436 first_pfn, max_low_pfn);
438 printk("Node %u: bdata = %p, bdata->node_bootmem_map = %p\n",
439 node, NODE_DATA(node)->bdata,
440 NODE_DATA(node)->bdata->node_bootmem_map);
443 * Register fully available RAM pages with the bootmem
446 pages = max_low_pfn - first_pfn;
447 free_bootmem_node (NODE_DATA(node), PFN_PHYS(first_pfn),
451 * Reserve space for the kernel image (if present in
454 if ((kern_start >= PFN_PHYS(first_pfn)) &&
455 (kern_start < PFN_PHYS(max_pfn))) {
456 printk("Node %u: Kernel image %08lx - %08lx\n",
457 node, kern_start, kern_end);
458 reserve_bootmem_node(NODE_DATA(node), kern_start,
459 kern_end - kern_start);
462 /* ...the bootmem bitmap... */
463 reserve_bootmem_node(NODE_DATA(node),
464 PFN_PHYS(bootmap_pfn),
467 /* ...any RAMDISK images... */
468 for (res = mem_ramdisk; res; res = res->next) {
469 if (res->addr > PFN_PHYS(max_pfn))
472 if (res->addr >= PFN_PHYS(first_pfn)) {
473 printk("Node %u: RAMDISK %08lx - %08lx\n",
475 (unsigned long)res->addr,
476 (unsigned long)(res->addr + res->size));
477 reserve_bootmem_node(NODE_DATA(node),
478 res->addr, res->size);
482 /* ...and any other reserved regions. */
483 for (res = mem_reserved; res; res = res->next) {
484 if (res->addr > PFN_PHYS(max_pfn))
487 if (res->addr >= PFN_PHYS(first_pfn)) {
488 printk("Node %u: Reserved %08lx - %08lx\n",
490 (unsigned long)res->addr,
491 (unsigned long)(res->addr + res->size));
492 reserve_bootmem_node(NODE_DATA(node),
493 res->addr, res->size);
497 node_set_online(node);
501 void __init setup_arch (char **cmdline_p)
505 parse_tags(bootloader_tags);
511 cpu_clk = clk_get(NULL, "cpu");
512 if (IS_ERR(cpu_clk)) {
513 printk(KERN_WARNING "Warning: Unable to get CPU clock\n");
515 unsigned long cpu_hz = clk_get_rate(cpu_clk);
518 * Well, duh, but it's probably a good idea to
519 * increment the use count.
523 boot_cpu_data.clk = cpu_clk;
524 boot_cpu_data.loops_per_jiffy = cpu_hz * 4;
525 printk("CPU: Running at %lu.%03lu MHz\n",
526 ((cpu_hz + 500) / 1000) / 1000,
527 ((cpu_hz + 500) / 1000) % 1000);
530 init_mm.start_code = (unsigned long) &_text;
531 init_mm.end_code = (unsigned long) &_etext;
532 init_mm.end_data = (unsigned long) &_edata;
533 init_mm.brk = (unsigned long) &_end;
535 strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
536 *cmdline_p = command_line;
541 board_setup_fbmem(fbmem_start, fbmem_size);
544 conswitchp = &dummy_con;