Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* |
| 2 | * |
| 3 | * linux/arch/cris/kernel/setup.c |
| 4 | * |
| 5 | * Copyright (C) 1995 Linus Torvalds |
| 6 | * Copyright (c) 2001 Axis Communications AB |
| 7 | */ |
| 8 | |
| 9 | /* |
| 10 | * This file handles the architecture-dependent parts of initialization |
| 11 | */ |
| 12 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 13 | #include <linux/init.h> |
| 14 | #include <linux/mm.h> |
| 15 | #include <linux/bootmem.h> |
| 16 | #include <asm/pgtable.h> |
| 17 | #include <linux/seq_file.h> |
Jon Smirl | 894673e | 2006-07-10 04:44:13 -0700 | [diff] [blame] | 18 | #include <linux/screen_info.h> |
Mikael Starvik | 7cf32ca | 2005-07-27 11:44:38 -0700 | [diff] [blame] | 19 | #include <linux/utsname.h> |
Dave Hansen | 22a9835 | 2006-03-27 01:16:04 -0800 | [diff] [blame] | 20 | #include <linux/pfn.h> |
Jesper Nilsson | 60dead5 | 2008-01-28 16:39:00 +0100 | [diff] [blame] | 21 | #include <linux/cpu.h> |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 22 | #include <asm/setup.h> |
| 23 | |
| 24 | /* |
| 25 | * Setup options |
| 26 | */ |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 27 | struct screen_info screen_info; |
| 28 | |
| 29 | extern int root_mountflags; |
| 30 | extern char _etext, _edata, _end; |
| 31 | |
Alon Bar-Lev | 87e1f9c | 2007-02-12 00:54:09 -0800 | [diff] [blame] | 32 | char __initdata cris_command_line[COMMAND_LINE_SIZE] = { 0, }; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 33 | |
| 34 | extern const unsigned long text_start, edata; /* set by the linker script */ |
| 35 | extern unsigned long dram_start, dram_end; |
| 36 | |
| 37 | extern unsigned long romfs_start, romfs_length, romfs_in_flash; /* from head.S */ |
| 38 | |
Jesper Nilsson | 60dead5 | 2008-01-28 16:39:00 +0100 | [diff] [blame] | 39 | static struct cpu cpu_devices[NR_CPUS]; |
| 40 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 41 | extern void show_etrax_copyright(void); /* arch-vX/kernel/setup.c */ |
| 42 | |
| 43 | /* This mainly sets up the memory area, and can be really confusing. |
| 44 | * |
| 45 | * The physical DRAM is virtually mapped into dram_start to dram_end |
| 46 | * (usually c0000000 to c0000000 + DRAM size). The physical address is |
| 47 | * given by the macro __pa(). |
| 48 | * |
| 49 | * In this DRAM, the kernel code and data is loaded, in the beginning. |
Jesper Nilsson | 60dead5 | 2008-01-28 16:39:00 +0100 | [diff] [blame] | 50 | * It really starts at c0004000 to make room for some special pages - |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 51 | * the start address is text_start. The kernel data ends at _end. After |
| 52 | * this the ROM filesystem is appended (if there is any). |
Jesper Nilsson | 60dead5 | 2008-01-28 16:39:00 +0100 | [diff] [blame] | 53 | * |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 54 | * Between this address and dram_end, we have RAM pages usable to the |
| 55 | * boot code and the system. |
| 56 | * |
| 57 | */ |
| 58 | |
Jesper Nilsson | 60dead5 | 2008-01-28 16:39:00 +0100 | [diff] [blame] | 59 | void __init setup_arch(char **cmdline_p) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 60 | { |
| 61 | extern void init_etrax_debug(void); |
| 62 | unsigned long bootmap_size; |
| 63 | unsigned long start_pfn, max_pfn; |
| 64 | unsigned long memory_start; |
| 65 | |
Jesper Nilsson | 60dead5 | 2008-01-28 16:39:00 +0100 | [diff] [blame] | 66 | /* register an initial console printing routine for printk's */ |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 67 | |
| 68 | init_etrax_debug(); |
| 69 | |
| 70 | /* we should really poll for DRAM size! */ |
| 71 | |
| 72 | high_memory = &dram_end; |
| 73 | |
| 74 | if(romfs_in_flash || !romfs_length) { |
| 75 | /* if we have the romfs in flash, or if there is no rom filesystem, |
| 76 | * our free area starts directly after the BSS |
| 77 | */ |
| 78 | memory_start = (unsigned long) &_end; |
| 79 | } else { |
| 80 | /* otherwise the free area starts after the ROM filesystem */ |
| 81 | printk("ROM fs in RAM, size %lu bytes\n", romfs_length); |
| 82 | memory_start = romfs_start + romfs_length; |
| 83 | } |
| 84 | |
| 85 | /* process 1's initial memory region is the kernel code/data */ |
| 86 | |
| 87 | init_mm.start_code = (unsigned long) &text_start; |
| 88 | init_mm.end_code = (unsigned long) &_etext; |
| 89 | init_mm.end_data = (unsigned long) &_edata; |
| 90 | init_mm.brk = (unsigned long) &_end; |
| 91 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 92 | /* min_low_pfn points to the start of DRAM, start_pfn points |
| 93 | * to the first DRAM pages after the kernel, and max_low_pfn |
| 94 | * to the end of DRAM. |
| 95 | */ |
| 96 | |
| 97 | /* |
| 98 | * partially used pages are not usable - thus |
| 99 | * we are rounding upwards: |
| 100 | */ |
| 101 | |
| 102 | start_pfn = PFN_UP(memory_start); /* usually c0000000 + kernel + romfs */ |
| 103 | max_pfn = PFN_DOWN((unsigned long)high_memory); /* usually c0000000 + dram size */ |
| 104 | |
| 105 | /* |
| 106 | * Initialize the boot-time allocator (start, end) |
| 107 | * |
| 108 | * We give it access to all our DRAM, but we could as well just have |
| 109 | * given it a small slice. No point in doing that though, unless we |
| 110 | * have non-contiguous memory and want the boot-stuff to be in, say, |
| 111 | * the smallest area. |
| 112 | * |
| 113 | * It will put a bitmap of the allocated pages in the beginning |
| 114 | * of the range we give it, but it won't mark the bitmaps pages |
| 115 | * as reserved. We have to do that ourselves below. |
| 116 | * |
| 117 | * We need to use init_bootmem_node instead of init_bootmem |
| 118 | * because our map starts at a quite high address (min_low_pfn). |
| 119 | */ |
| 120 | |
| 121 | max_low_pfn = max_pfn; |
| 122 | min_low_pfn = PAGE_OFFSET >> PAGE_SHIFT; |
| 123 | |
| 124 | bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, |
Jesper Nilsson | 60dead5 | 2008-01-28 16:39:00 +0100 | [diff] [blame] | 125 | min_low_pfn, |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 126 | max_low_pfn); |
| 127 | |
| 128 | /* And free all memory not belonging to the kernel (addr, size) */ |
| 129 | |
| 130 | free_bootmem(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn - start_pfn)); |
| 131 | |
| 132 | /* |
| 133 | * Reserve the bootmem bitmap itself as well. We do this in two |
| 134 | * steps (first step was init_bootmem()) because this catches |
| 135 | * the (very unlikely) case of us accidentally initializing the |
| 136 | * bootmem allocator with an invalid RAM area. |
| 137 | * |
| 138 | * Arguments are start, size |
| 139 | */ |
| 140 | |
Bernhard Walle | 72a7fe3 | 2008-02-07 00:15:17 -0800 | [diff] [blame] | 141 | reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size, BOOTMEM_DEFAULT); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 142 | |
| 143 | /* paging_init() sets up the MMU and marks all pages as reserved */ |
| 144 | |
| 145 | paging_init(); |
| 146 | |
Mikael Starvik | 7cf32ca | 2005-07-27 11:44:38 -0700 | [diff] [blame] | 147 | *cmdline_p = cris_command_line; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 148 | |
| 149 | #ifdef CONFIG_ETRAX_CMDLINE |
Mikael Starvik | 7cf32ca | 2005-07-27 11:44:38 -0700 | [diff] [blame] | 150 | if (!strcmp(cris_command_line, "")) { |
| 151 | strlcpy(cris_command_line, CONFIG_ETRAX_CMDLINE, COMMAND_LINE_SIZE); |
| 152 | cris_command_line[COMMAND_LINE_SIZE - 1] = '\0'; |
| 153 | } |
| 154 | #endif |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 155 | |
| 156 | /* Save command line for future references. */ |
Alon Bar-Lev | 87e1f9c | 2007-02-12 00:54:09 -0800 | [diff] [blame] | 157 | memcpy(boot_command_line, cris_command_line, COMMAND_LINE_SIZE); |
| 158 | boot_command_line[COMMAND_LINE_SIZE - 1] = '\0'; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 159 | |
| 160 | /* give credit for the CRIS port */ |
| 161 | show_etrax_copyright(); |
Mikael Starvik | 7cf32ca | 2005-07-27 11:44:38 -0700 | [diff] [blame] | 162 | |
| 163 | /* Setup utsname */ |
Serge E. Hallyn | 96b644b | 2006-10-02 02:18:13 -0700 | [diff] [blame] | 164 | strcpy(init_utsname()->machine, cris_machine_name); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 165 | } |
| 166 | |
| 167 | static void *c_start(struct seq_file *m, loff_t *pos) |
| 168 | { |
Mikael Starvik | 7cf32ca | 2005-07-27 11:44:38 -0700 | [diff] [blame] | 169 | return *pos < NR_CPUS ? (void *)(int)(*pos + 1): NULL; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 170 | } |
| 171 | |
| 172 | static void *c_next(struct seq_file *m, void *v, loff_t *pos) |
| 173 | { |
| 174 | ++*pos; |
Mikael Starvik | 7cf32ca | 2005-07-27 11:44:38 -0700 | [diff] [blame] | 175 | return c_start(m, pos); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 176 | } |
| 177 | |
| 178 | static void c_stop(struct seq_file *m, void *v) |
| 179 | { |
| 180 | } |
| 181 | |
| 182 | extern int show_cpuinfo(struct seq_file *m, void *v); |
| 183 | |
Jesper Nilsson | 60dead5 | 2008-01-28 16:39:00 +0100 | [diff] [blame] | 184 | const struct seq_operations cpuinfo_op = { |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 185 | .start = c_start, |
| 186 | .next = c_next, |
| 187 | .stop = c_stop, |
| 188 | .show = show_cpuinfo, |
| 189 | }; |
| 190 | |
Jesper Nilsson | 60dead5 | 2008-01-28 16:39:00 +0100 | [diff] [blame] | 191 | static int __init topology_init(void) |
| 192 | { |
| 193 | int i; |
| 194 | |
| 195 | for_each_possible_cpu(i) { |
| 196 | return register_cpu(&cpu_devices[i], i); |
| 197 | } |
| 198 | |
| 199 | return 0; |
| 200 | } |
| 201 | |
| 202 | subsys_initcall(topology_init); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 203 | |