1 /*
2 * linux/arch/arm/kernel/setup.c
3 *
4 * Copyright (C) 1995-2001 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10 #include <linux/config.h>
11 #include <linux/kernel.h>
12 #include <linux/stddef.h>
13 #include <linux/ioport.h>
14 #include <linux/delay.h>
15 #include <linux/utsname.h>
16 #include <linux/blk.h>
17 #include <linux/console.h>
18 #include <linux/bootmem.h>
19 #include <linux/seq_file.h>
20 #include <linux/list.h>
21 #include <linux/timer.h>
22 #include <linux/init.h>
23
24 #include <asm/elf.h>
25 #include <asm/hardware.h>
26 #include <asm/io.h>
27 #include <asm/procinfo.h>
28 #include <asm/setup.h>
29 #include <asm/mach-types.h>
30
31 #include <asm/mach/arch.h>
32 #include <asm/mach/irq.h>
33
34 #ifndef MEM_SIZE
35 #define MEM_SIZE (16*1024*1024)
36 #endif
37
38 #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
39 char fpe_type[8];
40
fpe_setup(char * line)41 static int __init fpe_setup(char *line)
42 {
43 memcpy(fpe_type, line, 8);
44 return 1;
45 }
46
47 __setup("fpe=", fpe_setup);
48 #endif
49
50 extern unsigned int mem_fclk_21285;
51 extern void paging_init(struct meminfo *, struct machine_desc *desc);
52 extern void convert_to_tag_list(struct tag *tags);
53 extern void squash_mem_tags(struct tag *tag);
54 extern void bootmem_init(struct meminfo *);
55 extern void reboot_setup(char *str);
56 extern int root_mountflags;
57 extern int _stext, _text, _etext, _edata, _end;
58
59 unsigned int processor_id;
60 unsigned int __machine_arch_type;
61 unsigned int system_rev;
62 unsigned int system_serial_low;
63 unsigned int system_serial_high;
64 unsigned int elf_hwcap;
65
66 #ifdef MULTI_CPU
67 struct processor processor;
68 #endif
69
70 unsigned char aux_device_present;
71 char elf_platform[ELF_PLATFORM_SIZE];
72 char saved_command_line[COMMAND_LINE_SIZE];
73 unsigned long phys_initrd_start __initdata = 0;
74 unsigned long phys_initrd_size __initdata = 0;
75
76 static struct meminfo meminfo __initdata = { 0, };
77 static const char *cpu_name;
78 static const char *machine_name;
79 static char command_line[COMMAND_LINE_SIZE];
80
81 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
82 static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
83 #define ENDIANNESS ((char)endian_test.l)
84
85 /*
86 * Standard memory resources
87 */
88 static struct resource mem_res[] = {
89 { "Video RAM", 0, 0, IORESOURCE_MEM },
90 { "Kernel code", 0, 0, IORESOURCE_MEM },
91 { "Kernel data", 0, 0, IORESOURCE_MEM }
92 };
93
94 #define video_ram mem_res[0]
95 #define kernel_code mem_res[1]
96 #define kernel_data mem_res[2]
97
98 static struct resource io_res[] = {
99 { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY },
100 { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY },
101 { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY }
102 };
103
104 #define lp0 io_res[0]
105 #define lp1 io_res[1]
106 #define lp2 io_res[2]
107
setup_processor(void)108 static void __init setup_processor(void)
109 {
110 extern struct proc_info_list __proc_info_begin, __proc_info_end;
111 struct proc_info_list *list;
112
113 /*
114 * locate processor in the list of supported processor
115 * types. The linker builds this table for us from the
116 * entries in arch/arm/mm/proc-*.S
117 */
118 for (list = &__proc_info_begin; list < &__proc_info_end ; list++)
119 if ((processor_id & list->cpu_mask) == list->cpu_val)
120 break;
121
122 /*
123 * If processor type is unrecognised, then we
124 * can do nothing...
125 */
126 if (list >= &__proc_info_end) {
127 printk("CPU configuration botched (ID %08x), unable "
128 "to continue.\n", processor_id);
129 while (1);
130 }
131
132 cpu_name = list->info->cpu_name;
133
134 #ifdef MULTI_CPU
135 processor = *list->proc;
136 #endif
137
138 printk("CPU: %s revision %d\n", cpu_name, (int)processor_id & 15);
139
140 sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
141 sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
142 elf_hwcap = list->elf_hwcap;
143
144 cpu_proc_init();
145 }
146
setup_machine(unsigned int nr)147 static struct machine_desc * __init setup_machine(unsigned int nr)
148 {
149 extern struct machine_desc __arch_info_begin, __arch_info_end;
150 struct machine_desc *list;
151
152 /*
153 * locate architecture in the list of supported architectures.
154 */
155 for (list = &__arch_info_begin; list < &__arch_info_end; list++)
156 if (list->nr == nr)
157 break;
158
159 /*
160 * If the architecture type is not recognised, then we
161 * can co nothing...
162 */
163 if (list >= &__arch_info_end) {
164 printk("Architecture configuration botched (nr %d), unable "
165 "to continue.\n", nr);
166 while (1);
167 }
168
169 printk("Machine: %s\n", list->name);
170
171 return list;
172 }
173
174 /*
175 * Initial parsing of the command line. We need to pick out the
176 * memory size. We look for mem=size@start, where start and size
177 * are "size[KkMm]"
178 */
179 static void __init
parse_cmdline(struct meminfo * mi,char ** cmdline_p,char * from)180 parse_cmdline(struct meminfo *mi, char **cmdline_p, char *from)
181 {
182 char c = ' ', *to = command_line;
183 int usermem = 0, len = 0;
184
185 for (;;) {
186 if (c == ' ' && !memcmp(from, "mem=", 4)) {
187 unsigned long size, start;
188
189 if (to != command_line)
190 to -= 1;
191
192 /*
193 * If the user specifies memory size, we
194 * blow away any automatically generated
195 * size.
196 */
197 if (usermem == 0) {
198 usermem = 1;
199 mi->nr_banks = 0;
200 }
201
202 start = PHYS_OFFSET;
203 size = memparse(from + 4, &from);
204 if (*from == '@')
205 start = memparse(from + 1, &from);
206
207 mi->bank[mi->nr_banks].start = start;
208 mi->bank[mi->nr_banks].size = size;
209 mi->bank[mi->nr_banks].node = PHYS_TO_NID(start);
210 mi->nr_banks += 1;
211 } else if (c == ' ' && !memcmp(from, "initrd=", 7)) {
212 unsigned long start, size;
213
214 /*
215 * Remove space character
216 */
217 if (to != command_line)
218 to -= 1;
219
220 start = memparse(from + 7, &from);
221 if (*from == ',') {
222 size = memparse(from + 1, &from);
223
224 phys_initrd_start = start;
225 phys_initrd_size = size;
226 }
227 }
228 c = *from++;
229 if (!c)
230 break;
231 if (COMMAND_LINE_SIZE <= ++len)
232 break;
233 *to++ = c;
234 }
235 *to = '\0';
236 *cmdline_p = command_line;
237 }
238
239 void __init
setup_ramdisk(int doload,int prompt,int image_start,unsigned int rd_sz)240 setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
241 {
242 #ifdef CONFIG_BLK_DEV_RAM
243 extern int rd_size, rd_image_start, rd_prompt, rd_doload;
244
245 rd_image_start = image_start;
246 rd_prompt = prompt;
247 rd_doload = doload;
248
249 if (rd_sz)
250 rd_size = rd_sz;
251 #endif
252 }
253
254 /*
255 * initial ram disk
256 */
setup_initrd(unsigned int start,unsigned int size)257 void __init setup_initrd(unsigned int start, unsigned int size)
258 {
259 #ifdef CONFIG_BLK_DEV_INITRD
260 if (start == 0)
261 size = 0;
262 phys_initrd_start = __virt_to_phys(start);
263 phys_initrd_size = size;
264 #endif
265 }
266
267 static void __init
request_standard_resources(struct meminfo * mi,struct machine_desc * mdesc)268 request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
269 {
270 struct resource *res;
271 int i;
272
273 kernel_code.start = __virt_to_phys(init_mm.start_code);
274 kernel_code.end = __virt_to_phys(init_mm.end_code - 1);
275 kernel_data.start = __virt_to_phys(init_mm.end_code);
276 kernel_data.end = __virt_to_phys(init_mm.brk - 1);
277
278 for (i = 0; i < mi->nr_banks; i++) {
279 unsigned long virt_start, virt_end;
280
281 if (mi->bank[i].size == 0)
282 continue;
283
284 virt_start = __phys_to_virt(mi->bank[i].start);
285 virt_end = virt_start + mi->bank[i].size - 1;
286
287 res = alloc_bootmem_low(sizeof(*res));
288 res->name = "System RAM";
289 res->start = __virt_to_phys(virt_start);
290 res->end = __virt_to_phys(virt_end);
291 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
292
293 request_resource(&iomem_resource, res);
294
295 if (kernel_code.start >= res->start &&
296 kernel_code.end <= res->end)
297 request_resource(res, &kernel_code);
298 if (kernel_data.start >= res->start &&
299 kernel_data.end <= res->end)
300 request_resource(res, &kernel_data);
301 }
302
303 if (mdesc->video_start) {
304 video_ram.start = mdesc->video_start;
305 video_ram.end = mdesc->video_end;
306 request_resource(&iomem_resource, &video_ram);
307 }
308
309 /*
310 * Some machines don't have the possibility of ever
311 * possessing lp0, lp1 or lp2
312 */
313 if (mdesc->reserve_lp0)
314 request_resource(&ioport_resource, &lp0);
315 if (mdesc->reserve_lp1)
316 request_resource(&ioport_resource, &lp1);
317 if (mdesc->reserve_lp2)
318 request_resource(&ioport_resource, &lp2);
319 }
320
321 /*
322 * Tag parsing.
323 *
324 * This is the new way of passing data to the kernel at boot time. Rather
325 * than passing a fixed inflexible structure to the kernel, we pass a list
326 * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE
327 * tag for the list to be recognised (to distinguish the tagged list from
328 * a param_struct). The list is terminated with a zero-length tag (this tag
329 * is not parsed in any way).
330 */
parse_tag_core(const struct tag * tag)331 static int __init parse_tag_core(const struct tag *tag)
332 {
333 if (tag->hdr.size > 2) {
334 if ((tag->u.core.flags & 1) == 0)
335 root_mountflags &= ~MS_RDONLY;
336 ROOT_DEV = to_kdev_t(tag->u.core.rootdev);
337 }
338 return 0;
339 }
340
341 __tagtable(ATAG_CORE, parse_tag_core);
342
parse_tag_mem32(const struct tag * tag)343 static int __init parse_tag_mem32(const struct tag *tag)
344 {
345 if (meminfo.nr_banks >= NR_BANKS) {
346 printk(KERN_WARNING
347 "Ignoring memory bank 0x%08x size %dKB\n",
348 tag->u.mem.start, tag->u.mem.size / 1024);
349 return -EINVAL;
350 }
351 meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start;
352 meminfo.bank[meminfo.nr_banks].size = tag->u.mem.size;
353 meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(tag->u.mem.start);
354 meminfo.nr_banks += 1;
355
356 return 0;
357 }
358
359 __tagtable(ATAG_MEM, parse_tag_mem32);
360
361 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
362 struct screen_info screen_info = {
363 .orig_video_lines = 30,
364 .orig_video_cols = 80,
365 .orig_video_mode = 0,
366 .orig_video_ega_bx = 0,
367 .orig_video_isVGA = 1,
368 .orig_video_points = 8
369 };
370
parse_tag_videotext(const struct tag * tag)371 static int __init parse_tag_videotext(const struct tag *tag)
372 {
373 screen_info.orig_x = tag->u.videotext.x;
374 screen_info.orig_y = tag->u.videotext.y;
375 screen_info.orig_video_page = tag->u.videotext.video_page;
376 screen_info.orig_video_mode = tag->u.videotext.video_mode;
377 screen_info.orig_video_cols = tag->u.videotext.video_cols;
378 screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
379 screen_info.orig_video_lines = tag->u.videotext.video_lines;
380 screen_info.orig_video_isVGA = tag->u.videotext.video_isvga;
381 screen_info.orig_video_points = tag->u.videotext.video_points;
382 return 0;
383 }
384
385 __tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
386 #endif
387
parse_tag_ramdisk(const struct tag * tag)388 static int __init parse_tag_ramdisk(const struct tag *tag)
389 {
390 setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
391 (tag->u.ramdisk.flags & 2) == 0,
392 tag->u.ramdisk.start, tag->u.ramdisk.size);
393 return 0;
394 }
395
396 __tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
397
parse_tag_initrd(const struct tag * tag)398 static int __init parse_tag_initrd(const struct tag *tag)
399 {
400 phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
401 phys_initrd_size = tag->u.initrd.size;
402 return 0;
403 }
404
405 __tagtable(ATAG_INITRD, parse_tag_initrd);
406
parse_tag_initrd2(const struct tag * tag)407 static int __init parse_tag_initrd2(const struct tag *tag)
408 {
409 phys_initrd_start = tag->u.initrd.start;
410 phys_initrd_size = tag->u.initrd.size;
411 return 0;
412 }
413
414 __tagtable(ATAG_INITRD2, parse_tag_initrd2);
415
parse_tag_serialnr(const struct tag * tag)416 static int __init parse_tag_serialnr(const struct tag *tag)
417 {
418 system_serial_low = tag->u.serialnr.low;
419 system_serial_high = tag->u.serialnr.high;
420 return 0;
421 }
422
423 __tagtable(ATAG_SERIAL, parse_tag_serialnr);
424
parse_tag_revision(const struct tag * tag)425 static int __init parse_tag_revision(const struct tag *tag)
426 {
427 system_rev = tag->u.revision.rev;
428 return 0;
429 }
430
431 __tagtable(ATAG_REVISION, parse_tag_revision);
432
parse_tag_cmdline(const struct tag * tag)433 static int __init parse_tag_cmdline(const struct tag *tag)
434 {
435 strncpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
436 default_command_line[COMMAND_LINE_SIZE - 1] = '\0';
437 return 0;
438 }
439
440 __tagtable(ATAG_CMDLINE, parse_tag_cmdline);
441
442 /*
443 * Scan the tag table for this tag, and call its parse function.
444 * The tag table is built by the linker from all the __tagtable
445 * declarations.
446 */
parse_tag(const struct tag * tag)447 static int __init parse_tag(const struct tag *tag)
448 {
449 extern struct tagtable __tagtable_begin, __tagtable_end;
450 struct tagtable *t;
451
452 for (t = &__tagtable_begin; t < &__tagtable_end; t++)
453 if (tag->hdr.tag == t->tag) {
454 t->parse(tag);
455 break;
456 }
457
458 return t < &__tagtable_end;
459 }
460
461 /*
462 * Parse all tags in the list, checking both the global and architecture
463 * specific tag tables.
464 */
parse_tags(const struct tag * t)465 static void __init parse_tags(const struct tag *t)
466 {
467 for (; t->hdr.size; t = tag_next(t))
468 if (!parse_tag(t))
469 printk(KERN_WARNING
470 "Ignoring unrecognised tag 0x%08x\n",
471 t->hdr.tag);
472 }
473
474 static struct init_tags {
475 struct tag_header hdr1;
476 struct tag_core core;
477 struct tag_header hdr2;
478 struct tag_mem32 mem;
479 struct tag_header hdr3;
480 } init_tags __initdata = {
481 { tag_size(tag_core), ATAG_CORE },
482 { 1, PAGE_SIZE, 0xff },
483 { tag_size(tag_mem32), ATAG_MEM },
484 { MEM_SIZE, PHYS_OFFSET },
485 { 0, ATAG_NONE }
486 };
487
setup_arch(char ** cmdline_p)488 void __init setup_arch(char **cmdline_p)
489 {
490 struct tag *tags = (struct tag *)&init_tags;
491 struct machine_desc *mdesc;
492 char *from = default_command_line;
493
494 ROOT_DEV = MKDEV(0, 255);
495
496 setup_processor();
497 mdesc = setup_machine(machine_arch_type);
498 machine_name = mdesc->name;
499
500 if (mdesc->soft_reboot)
501 reboot_setup("s");
502
503 if (mdesc->param_offset)
504 tags = phys_to_virt(mdesc->param_offset);
505
506 /*
507 * Do the machine-specific fixups before we parse the
508 * parameters or tags.
509 */
510 if (mdesc->fixup)
511 mdesc->fixup(mdesc, (struct param_struct *)tags,
512 &from, &meminfo);
513
514 /*
515 * If we have the old style parameters, convert them to
516 * a tag list.
517 */
518 if (tags->hdr.tag != ATAG_CORE)
519 convert_to_tag_list(tags);
520
521 if (tags->hdr.tag == ATAG_CORE) {
522 if (meminfo.nr_banks != 0)
523 squash_mem_tags(tags);
524 parse_tags(tags);
525 }
526
527 if (meminfo.nr_banks == 0) {
528 meminfo.nr_banks = 1;
529 meminfo.bank[0].start = PHYS_OFFSET;
530 meminfo.bank[0].size = MEM_SIZE;
531 }
532
533 init_mm.start_code = (unsigned long) &_text;
534 init_mm.end_code = (unsigned long) &_etext;
535 init_mm.end_data = (unsigned long) &_edata;
536 init_mm.brk = (unsigned long) &_end;
537
538 memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
539 saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
540 parse_cmdline(&meminfo, cmdline_p, from);
541 bootmem_init(&meminfo);
542 paging_init(&meminfo, mdesc);
543 request_standard_resources(&meminfo, mdesc);
544
545 /*
546 * Set up various architecture-specific pointers
547 */
548 init_arch_irq = mdesc->init_irq;
549
550 #ifdef CONFIG_VT
551 #if defined(CONFIG_VGA_CONSOLE)
552 conswitchp = &vga_con;
553 #elif defined(CONFIG_DUMMY_CONSOLE)
554 conswitchp = &dummy_con;
555 #endif
556 #endif
557 }
558
559 static const char *hwcap_str[] = {
560 "swp",
561 "half",
562 "thumb",
563 "26bit",
564 "fastmult",
565 "fpa",
566 "vfp",
567 "edsp",
568 NULL
569 };
570
c_show(struct seq_file * m,void * v)571 static int c_show(struct seq_file *m, void *v)
572 {
573 int i;
574
575 seq_printf(m, "Processor\t: %s rev %d (%s)\n",
576 cpu_name, (int)processor_id & 15, elf_platform);
577
578 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
579 loops_per_jiffy / (500000/HZ),
580 (loops_per_jiffy / (5000/HZ)) % 100);
581
582 /* dump out the processor features */
583 seq_puts(m, "Features\t: ");
584
585 for (i = 0; hwcap_str[i]; i++)
586 if (elf_hwcap & (1 << i))
587 seq_printf(m, "%s ", hwcap_str[i]);
588
589 seq_puts(m, "\n\n");
590
591 seq_printf(m, "Hardware\t: %s\n", machine_name);
592 seq_printf(m, "Revision\t: %04x\n", system_rev);
593 seq_printf(m, "Serial\t\t: %08x%08x\n",
594 system_serial_high, system_serial_low);
595
596 return 0;
597 }
598
c_start(struct seq_file * m,loff_t * pos)599 static void *c_start(struct seq_file *m, loff_t *pos)
600 {
601 return *pos < 1 ? (void *)1 : NULL;
602 }
603
c_next(struct seq_file * m,void * v,loff_t * pos)604 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
605 {
606 ++*pos;
607 return NULL;
608 }
609
c_stop(struct seq_file * m,void * v)610 static void c_stop(struct seq_file *m, void *v)
611 {
612 }
613
614 struct seq_operations cpuinfo_op = {
615 .start = c_start,
616 .next = c_next,
617 .stop = c_stop,
618 .show = c_show
619 };
620