aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/setup.c')
-rw-r--r--arch/sh/kernel/setup.c210
1 files changed, 38 insertions, 172 deletions
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index c2772913593..de8e6e2f2c8 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -23,6 +23,7 @@
23#include <linux/kexec.h> 23#include <linux/kexec.h>
24#include <asm/uaccess.h> 24#include <asm/uaccess.h>
25#include <asm/io.h> 25#include <asm/io.h>
26#include <asm/page.h>
26#include <asm/sections.h> 27#include <asm/sections.h>
27#include <asm/irq.h> 28#include <asm/irq.h>
28#include <asm/setup.h> 29#include <asm/setup.h>
@@ -41,20 +42,19 @@ extern void * __rd_start, * __rd_end;
41 * The bigger value means no problem. 42 * The bigger value means no problem.
42 */ 43 */
43struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, }; 44struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, };
45
46/*
47 * The machine vector. First entry in .machvec.init, or clobbered by
48 * sh_mv= on the command line, prior to .machvec.init teardown.
49 */
50struct sh_machine_vector sh_mv = { .mv_name = "generic", };
51
44#ifdef CONFIG_VT 52#ifdef CONFIG_VT
45struct screen_info screen_info; 53struct screen_info screen_info;
46#endif 54#endif
47 55
48#if defined(CONFIG_SH_UNKNOWN)
49struct sh_machine_vector sh_mv;
50#endif
51
52extern int root_mountflags; 56extern int root_mountflags;
53 57
54#define MV_NAME_SIZE 32
55
56static struct sh_machine_vector* __init get_mv_byname(const char* name);
57
58/* 58/*
59 * This is set up by the setup-routine at boot-time 59 * This is set up by the setup-routine at boot-time
60 */ 60 */
@@ -80,131 +80,17 @@ static struct resource data_resource = { .name = "Kernel data", };
80 80
81unsigned long memory_start, memory_end; 81unsigned long memory_start, memory_end;
82 82
83static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE], 83static int __init early_parse_mem(char *p)
84 struct sh_machine_vector** mvp,
85 unsigned long *mv_io_base)
86{ 84{
87 char c = ' ', *to = command_line, *from = COMMAND_LINE; 85 unsigned long size;
88 int len = 0;
89
90 /* Save unparsed command line copy for /proc/cmdline */
91 memcpy(boot_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
92 boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
93 86
94 memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START; 87 memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START;
95 memory_end = memory_start + __MEMORY_SIZE; 88 size = memparse(p, &p);
96 89 memory_end = memory_start + size;
97 for (;;) {
98 /*
99 * "mem=XXX[kKmM]" defines a size of memory.
100 */
101 if (c == ' ' && !memcmp(from, "mem=", 4)) {
102 if (to != command_line)
103 to--;
104 {
105 unsigned long mem_size;
106
107 mem_size = memparse(from+4, &from);
108 memory_end = memory_start + mem_size;
109 }
110 }
111
112 if (c == ' ' && !memcmp(from, "sh_mv=", 6)) {
113 char* mv_end;
114 char* mv_comma;
115 int mv_len;
116 if (to != command_line)
117 to--;
118 from += 6;
119 mv_end = strchr(from, ' ');
120 if (mv_end == NULL)
121 mv_end = from + strlen(from);
122
123 mv_comma = strchr(from, ',');
124 if ((mv_comma != NULL) && (mv_comma < mv_end)) {
125 int ints[3];
126 get_options(mv_comma+1, ARRAY_SIZE(ints), ints);
127 *mv_io_base = ints[1];
128 mv_len = mv_comma - from;
129 } else {
130 mv_len = mv_end - from;
131 }
132 if (mv_len > (MV_NAME_SIZE-1))
133 mv_len = MV_NAME_SIZE-1;
134 memcpy(mv_name, from, mv_len);
135 mv_name[mv_len] = '\0';
136 from = mv_end;
137
138 *mvp = get_mv_byname(mv_name);
139 }
140
141 c = *(from++);
142 if (!c)
143 break;
144 if (COMMAND_LINE_SIZE <= ++len)
145 break;
146 *(to++) = c;
147 }
148 *to = '\0';
149 *cmdline_p = command_line;
150}
151
152static int __init sh_mv_setup(char **cmdline_p)
153{
154#ifdef CONFIG_SH_UNKNOWN
155 extern struct sh_machine_vector mv_unknown;
156#endif
157 struct sh_machine_vector *mv = NULL;
158 char mv_name[MV_NAME_SIZE] = "";
159 unsigned long mv_io_base = 0;
160
161 parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base);
162
163#ifdef CONFIG_SH_UNKNOWN
164 if (mv == NULL) {
165 mv = &mv_unknown;
166 if (*mv_name != '\0') {
167 printk("Warning: Unsupported machine %s, using unknown\n",
168 mv_name);
169 }
170 }
171 sh_mv = *mv;
172#endif
173
174 /*
175 * Manually walk the vec, fill in anything that the board hasn't yet
176 * by hand, wrapping to the generic implementation.
177 */
178#define mv_set(elem) do { \
179 if (!sh_mv.mv_##elem) \
180 sh_mv.mv_##elem = generic_##elem; \
181} while (0)
182
183 mv_set(inb); mv_set(inw); mv_set(inl);
184 mv_set(outb); mv_set(outw); mv_set(outl);
185
186 mv_set(inb_p); mv_set(inw_p); mv_set(inl_p);
187 mv_set(outb_p); mv_set(outw_p); mv_set(outl_p);
188
189 mv_set(insb); mv_set(insw); mv_set(insl);
190 mv_set(outsb); mv_set(outsw); mv_set(outsl);
191
192 mv_set(readb); mv_set(readw); mv_set(readl);
193 mv_set(writeb); mv_set(writew); mv_set(writel);
194
195 mv_set(ioport_map);
196 mv_set(ioport_unmap);
197 mv_set(irq_demux);
198
199#ifdef CONFIG_SH_UNKNOWN
200 __set_io_port_base(mv_io_base);
201#endif
202
203 if (!sh_mv.mv_nr_irqs)
204 sh_mv.mv_nr_irqs = NR_IRQS;
205 90
206 return 0; 91 return 0;
207} 92}
93early_param("mem", early_parse_mem);
208 94
209/* 95/*
210 * Register fully available low RAM pages with the bootmem allocator. 96 * Register fully available low RAM pages with the bootmem allocator.
@@ -230,7 +116,7 @@ static void __init register_bootmem_low_pages(void)
230 free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages)); 116 free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
231} 117}
232 118
233void __init setup_bootmem_allocator(unsigned long start_pfn) 119void __init setup_bootmem_allocator(unsigned long free_pfn)
234{ 120{
235 unsigned long bootmap_size; 121 unsigned long bootmap_size;
236 122
@@ -239,9 +125,10 @@ void __init setup_bootmem_allocator(unsigned long start_pfn)
239 * bootstrap step all allocations (until the page allocator 125 * bootstrap step all allocations (until the page allocator
240 * is intact) must be done via bootmem_alloc(). 126 * is intact) must be done via bootmem_alloc().
241 */ 127 */
242 bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, 128 bootmap_size = init_bootmem_node(NODE_DATA(0), free_pfn,
243 min_low_pfn, max_low_pfn); 129 min_low_pfn, max_low_pfn);
244 130
131 add_active_range(0, min_low_pfn, max_low_pfn);
245 register_bootmem_low_pages(); 132 register_bootmem_low_pages();
246 133
247 node_set_online(0); 134 node_set_online(0);
@@ -254,7 +141,7 @@ void __init setup_bootmem_allocator(unsigned long start_pfn)
254 * an invalid RAM area. 141 * an invalid RAM area.
255 */ 142 */
256 reserve_bootmem(__MEMORY_START+PAGE_SIZE, 143 reserve_bootmem(__MEMORY_START+PAGE_SIZE,
257 (PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START); 144 (PFN_PHYS(free_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START);
258 145
259 /* 146 /*
260 * reserve physical page 0 - it's a special BIOS page on many boxes, 147 * reserve physical page 0 - it's a special BIOS page on many boxes,
@@ -262,6 +149,8 @@ void __init setup_bootmem_allocator(unsigned long start_pfn)
262 */ 149 */
263 reserve_bootmem(__MEMORY_START, PAGE_SIZE); 150 reserve_bootmem(__MEMORY_START, PAGE_SIZE);
264 151
152 sparse_memory_present_with_active_regions(0);
153
265#ifdef CONFIG_BLK_DEV_INITRD 154#ifdef CONFIG_BLK_DEV_INITRD
266 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); 155 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
267 if (&__rd_start != &__rd_end) { 156 if (&__rd_start != &__rd_end) {
@@ -315,10 +204,6 @@ void __init setup_arch(char **cmdline_p)
315{ 204{
316 enable_mmu(); 205 enable_mmu();
317 206
318#ifdef CONFIG_CMDLINE_BOOL
319 strcpy(COMMAND_LINE, CONFIG_CMDLINE);
320#endif
321
322 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); 207 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
323 208
324#ifdef CONFIG_BLK_DEV_RAM 209#ifdef CONFIG_BLK_DEV_RAM
@@ -339,9 +224,22 @@ void __init setup_arch(char **cmdline_p)
339 data_resource.start = virt_to_phys(_etext); 224 data_resource.start = virt_to_phys(_etext);
340 data_resource.end = virt_to_phys(_edata)-1; 225 data_resource.end = virt_to_phys(_edata)-1;
341 226
227 memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START;
228 memory_end = memory_start + __MEMORY_SIZE;
229
230#ifdef CONFIG_CMDLINE_BOOL
231 strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line));
232#else
233 strlcpy(command_line, COMMAND_LINE, sizeof(command_line));
234#endif
235
236 /* Save unparsed command line copy for /proc/cmdline */
237 memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
238 *cmdline_p = command_line;
239
342 parse_early_param(); 240 parse_early_param();
343 241
344 sh_mv_setup(cmdline_p); 242 sh_mv_setup();
345 243
346 /* 244 /*
347 * Find the highest page frame number we have available 245 * Find the highest page frame number we have available
@@ -355,8 +253,9 @@ void __init setup_arch(char **cmdline_p)
355 min_low_pfn = __MEMORY_START >> PAGE_SHIFT; 253 min_low_pfn = __MEMORY_START >> PAGE_SHIFT;
356 254
357 nodes_clear(node_online_map); 255 nodes_clear(node_online_map);
256
257 /* Setup bootmem with available RAM */
358 setup_memory(); 258 setup_memory();
359 paging_init();
360 sparse_init(); 259 sparse_init();
361 260
362#ifdef CONFIG_DUMMY_CONSOLE 261#ifdef CONFIG_DUMMY_CONSOLE
@@ -366,46 +265,13 @@ void __init setup_arch(char **cmdline_p)
366 /* Perform the machine specific initialisation */ 265 /* Perform the machine specific initialisation */
367 if (likely(sh_mv.mv_setup)) 266 if (likely(sh_mv.mv_setup))
368 sh_mv.mv_setup(cmdline_p); 267 sh_mv.mv_setup(cmdline_p);
369}
370
371struct sh_machine_vector* __init get_mv_byname(const char* name)
372{
373 extern long __machvec_start, __machvec_end;
374 struct sh_machine_vector *all_vecs =
375 (struct sh_machine_vector *)&__machvec_start;
376
377 int i, n = ((unsigned long)&__machvec_end
378 - (unsigned long)&__machvec_start)/
379 sizeof(struct sh_machine_vector);
380
381 for (i = 0; i < n; ++i) {
382 struct sh_machine_vector *mv = &all_vecs[i];
383 if (mv == NULL)
384 continue;
385 if (strcasecmp(name, get_system_type()) == 0) {
386 return mv;
387 }
388 }
389 return NULL;
390}
391
392static struct cpu cpu[NR_CPUS];
393
394static int __init topology_init(void)
395{
396 int cpu_id;
397 268
398 for_each_possible_cpu(cpu_id) 269 paging_init();
399 register_cpu(&cpu[cpu_id], cpu_id);
400
401 return 0;
402} 270}
403 271
404subsys_initcall(topology_init);
405
406static const char *cpu_name[] = { 272static const char *cpu_name[] = {
407 [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619", 273 [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619",
408 [CPU_SH7604] = "SH7604", [CPU_SH7300] = "SH7300", 274 [CPU_SH7300] = "SH7300",
409 [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", 275 [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
410 [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708", 276 [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708",
411 [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710", 277 [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710",
@@ -419,7 +285,7 @@ static const char *cpu_name[] = {
419 [CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780", 285 [CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780",
420 [CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343", 286 [CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343",
421 [CPU_SH7785] = "SH7785", [CPU_SH7722] = "SH7722", 287 [CPU_SH7785] = "SH7785", [CPU_SH7722] = "SH7722",
422 [CPU_SH_NONE] = "Unknown" 288 [CPU_SHX3] = "SH-X3", [CPU_SH_NONE] = "Unknown"
423}; 289};
424 290
425const char *get_cpu_subtype(struct sh_cpuinfo *c) 291const char *get_cpu_subtype(struct sh_cpuinfo *c)