Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | ||
1da177e4 LT |
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> | |
894673ee | 18 | #include <linux/screen_info.h> |
7cf32cad | 19 | #include <linux/utsname.h> |
22a9835c | 20 | #include <linux/pfn.h> |
60dead5a | 21 | #include <linux/cpu.h> |
a9f75ac5 RV |
22 | #include <linux/of.h> |
23 | #include <linux/of_fdt.h> | |
24 | #include <linux/of_platform.h> | |
1da177e4 | 25 | #include <asm/setup.h> |
b1a154db | 26 | #include <arch/system.h> |
1da177e4 LT |
27 | |
28 | /* | |
29 | * Setup options | |
30 | */ | |
1da177e4 LT |
31 | struct screen_info screen_info; |
32 | ||
33 | extern int root_mountflags; | |
34 | extern char _etext, _edata, _end; | |
35 | ||
87e1f9c6 | 36 | char __initdata cris_command_line[COMMAND_LINE_SIZE] = { 0, }; |
1da177e4 LT |
37 | |
38 | extern const unsigned long text_start, edata; /* set by the linker script */ | |
39 | extern unsigned long dram_start, dram_end; | |
40 | ||
41 | extern unsigned long romfs_start, romfs_length, romfs_in_flash; /* from head.S */ | |
42 | ||
60dead5a JN |
43 | static struct cpu cpu_devices[NR_CPUS]; |
44 | ||
1da177e4 LT |
45 | extern void show_etrax_copyright(void); /* arch-vX/kernel/setup.c */ |
46 | ||
47 | /* This mainly sets up the memory area, and can be really confusing. | |
48 | * | |
49 | * The physical DRAM is virtually mapped into dram_start to dram_end | |
50 | * (usually c0000000 to c0000000 + DRAM size). The physical address is | |
51 | * given by the macro __pa(). | |
52 | * | |
53 | * In this DRAM, the kernel code and data is loaded, in the beginning. | |
60dead5a | 54 | * It really starts at c0004000 to make room for some special pages - |
1da177e4 LT |
55 | * the start address is text_start. The kernel data ends at _end. After |
56 | * this the ROM filesystem is appended (if there is any). | |
60dead5a | 57 | * |
1da177e4 LT |
58 | * Between this address and dram_end, we have RAM pages usable to the |
59 | * boot code and the system. | |
60 | * | |
61 | */ | |
62 | ||
60dead5a | 63 | void __init setup_arch(char **cmdline_p) |
1da177e4 LT |
64 | { |
65 | extern void init_etrax_debug(void); | |
66 | unsigned long bootmap_size; | |
67 | unsigned long start_pfn, max_pfn; | |
68 | unsigned long memory_start; | |
69 | ||
a9f75ac5 RV |
70 | #ifdef CONFIG_OF |
71 | early_init_dt_scan(__dtb_start); | |
72 | #endif | |
73 | ||
60dead5a | 74 | /* register an initial console printing routine for printk's */ |
1da177e4 LT |
75 | |
76 | init_etrax_debug(); | |
77 | ||
78 | /* we should really poll for DRAM size! */ | |
79 | ||
80 | high_memory = &dram_end; | |
81 | ||
82 | if(romfs_in_flash || !romfs_length) { | |
83 | /* if we have the romfs in flash, or if there is no rom filesystem, | |
84 | * our free area starts directly after the BSS | |
85 | */ | |
86 | memory_start = (unsigned long) &_end; | |
87 | } else { | |
88 | /* otherwise the free area starts after the ROM filesystem */ | |
89 | printk("ROM fs in RAM, size %lu bytes\n", romfs_length); | |
90 | memory_start = romfs_start + romfs_length; | |
91 | } | |
92 | ||
93 | /* process 1's initial memory region is the kernel code/data */ | |
94 | ||
95 | init_mm.start_code = (unsigned long) &text_start; | |
96 | init_mm.end_code = (unsigned long) &_etext; | |
97 | init_mm.end_data = (unsigned long) &_edata; | |
98 | init_mm.brk = (unsigned long) &_end; | |
99 | ||
1da177e4 LT |
100 | /* min_low_pfn points to the start of DRAM, start_pfn points |
101 | * to the first DRAM pages after the kernel, and max_low_pfn | |
102 | * to the end of DRAM. | |
103 | */ | |
104 | ||
105 | /* | |
106 | * partially used pages are not usable - thus | |
107 | * we are rounding upwards: | |
108 | */ | |
109 | ||
110 | start_pfn = PFN_UP(memory_start); /* usually c0000000 + kernel + romfs */ | |
111 | max_pfn = PFN_DOWN((unsigned long)high_memory); /* usually c0000000 + dram size */ | |
112 | ||
113 | /* | |
114 | * Initialize the boot-time allocator (start, end) | |
115 | * | |
116 | * We give it access to all our DRAM, but we could as well just have | |
117 | * given it a small slice. No point in doing that though, unless we | |
118 | * have non-contiguous memory and want the boot-stuff to be in, say, | |
119 | * the smallest area. | |
120 | * | |
121 | * It will put a bitmap of the allocated pages in the beginning | |
122 | * of the range we give it, but it won't mark the bitmaps pages | |
123 | * as reserved. We have to do that ourselves below. | |
124 | * | |
125 | * We need to use init_bootmem_node instead of init_bootmem | |
126 | * because our map starts at a quite high address (min_low_pfn). | |
127 | */ | |
128 | ||
129 | max_low_pfn = max_pfn; | |
130 | min_low_pfn = PAGE_OFFSET >> PAGE_SHIFT; | |
131 | ||
132 | bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, | |
60dead5a | 133 | min_low_pfn, |
1da177e4 LT |
134 | max_low_pfn); |
135 | ||
136 | /* And free all memory not belonging to the kernel (addr, size) */ | |
137 | ||
138 | free_bootmem(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn - start_pfn)); | |
139 | ||
140 | /* | |
141 | * Reserve the bootmem bitmap itself as well. We do this in two | |
142 | * steps (first step was init_bootmem()) because this catches | |
143 | * the (very unlikely) case of us accidentally initializing the | |
144 | * bootmem allocator with an invalid RAM area. | |
145 | * | |
146 | * Arguments are start, size | |
147 | */ | |
148 | ||
72a7fe39 | 149 | reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size, BOOTMEM_DEFAULT); |
1da177e4 | 150 | |
a9f75ac5 RV |
151 | unflatten_and_copy_device_tree(); |
152 | ||
1da177e4 LT |
153 | /* paging_init() sets up the MMU and marks all pages as reserved */ |
154 | ||
155 | paging_init(); | |
156 | ||
7cf32cad | 157 | *cmdline_p = cris_command_line; |
1da177e4 LT |
158 | |
159 | #ifdef CONFIG_ETRAX_CMDLINE | |
7cf32cad MS |
160 | if (!strcmp(cris_command_line, "")) { |
161 | strlcpy(cris_command_line, CONFIG_ETRAX_CMDLINE, COMMAND_LINE_SIZE); | |
162 | cris_command_line[COMMAND_LINE_SIZE - 1] = '\0'; | |
163 | } | |
164 | #endif | |
1da177e4 LT |
165 | |
166 | /* Save command line for future references. */ | |
87e1f9c6 ABL |
167 | memcpy(boot_command_line, cris_command_line, COMMAND_LINE_SIZE); |
168 | boot_command_line[COMMAND_LINE_SIZE - 1] = '\0'; | |
1da177e4 LT |
169 | |
170 | /* give credit for the CRIS port */ | |
171 | show_etrax_copyright(); | |
7cf32cad MS |
172 | |
173 | /* Setup utsname */ | |
96b644bd | 174 | strcpy(init_utsname()->machine, cris_machine_name); |
1da177e4 LT |
175 | } |
176 | ||
c638b107 | 177 | #ifdef CONFIG_PROC_FS |
1da177e4 LT |
178 | static void *c_start(struct seq_file *m, loff_t *pos) |
179 | { | |
3e7be3fb | 180 | return *pos < nr_cpu_ids ? (void *)(int)(*pos + 1) : NULL; |
1da177e4 LT |
181 | } |
182 | ||
183 | static void *c_next(struct seq_file *m, void *v, loff_t *pos) | |
184 | { | |
185 | ++*pos; | |
7cf32cad | 186 | return c_start(m, pos); |
1da177e4 LT |
187 | } |
188 | ||
189 | static void c_stop(struct seq_file *m, void *v) | |
190 | { | |
191 | } | |
192 | ||
193 | extern int show_cpuinfo(struct seq_file *m, void *v); | |
194 | ||
60dead5a | 195 | const struct seq_operations cpuinfo_op = { |
1da177e4 LT |
196 | .start = c_start, |
197 | .next = c_next, | |
198 | .stop = c_stop, | |
199 | .show = show_cpuinfo, | |
200 | }; | |
c638b107 | 201 | #endif /* CONFIG_PROC_FS */ |
1da177e4 | 202 | |
60dead5a JN |
203 | static int __init topology_init(void) |
204 | { | |
205 | int i; | |
206 | ||
207 | for_each_possible_cpu(i) { | |
208 | return register_cpu(&cpu_devices[i], i); | |
209 | } | |
210 | ||
211 | return 0; | |
212 | } | |
213 | ||
214 | subsys_initcall(topology_init); | |
1da177e4 | 215 | |
a9f75ac5 RV |
216 | static int __init cris_of_init(void) |
217 | { | |
218 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | |
219 | return 0; | |
220 | } | |
221 | core_initcall(cris_of_init); |