1
2
3
4
5
6
7
8
9
10#include <linux/config.h>
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/stddef.h>
14#include <linux/ioport.h>
15#include <linux/delay.h>
16#include <linux/utsname.h>
17#include <linux/initrd.h>
18#include <linux/console.h>
19#include <linux/bootmem.h>
20#include <linux/seq_file.h>
21#include <linux/tty.h>
22#include <linux/init.h>
23#include <linux/root_dev.h>
24#include <linux/cpu.h>
25#include <linux/interrupt.h>
26
27#include <asm/cpu.h>
28#include <asm/elf.h>
29#include <asm/hardware.h>
30#include <asm/io.h>
31#include <asm/procinfo.h>
32#include <asm/setup.h>
33#include <asm/mach-types.h>
34#include <asm/cacheflush.h>
35#include <asm/tlbflush.h>
36
37#include <asm/mach/arch.h>
38#include <asm/mach/irq.h>
39#include <asm/mach/time.h>
40
41#ifndef MEM_SIZE
42#define MEM_SIZE (16*1024*1024)
43#endif
44
45#if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
46char fpe_type[8];
47
48static int __init fpe_setup(char *line)
49{
50 memcpy(fpe_type, line, 8);
51 return 1;
52}
53
54__setup("fpe=", fpe_setup);
55#endif
56
57extern unsigned int mem_fclk_21285;
58extern void paging_init(struct meminfo *, struct machine_desc *desc);
59extern void convert_to_tag_list(struct tag *tags);
60extern void squash_mem_tags(struct tag *tag);
61extern void reboot_setup(char *str);
62extern int root_mountflags;
63extern void _stext, _text, _etext, __data_start, _edata, _end;
64
65unsigned int processor_id;
66unsigned int __machine_arch_type;
67EXPORT_SYMBOL(__machine_arch_type);
68
69unsigned int system_rev;
70EXPORT_SYMBOL(system_rev);
71
72unsigned int system_serial_low;
73EXPORT_SYMBOL(system_serial_low);
74
75unsigned int system_serial_high;
76EXPORT_SYMBOL(system_serial_high);
77
78unsigned int elf_hwcap;
79EXPORT_SYMBOL(elf_hwcap);
80
81
82#ifdef MULTI_CPU
83struct processor processor;
84#endif
85#ifdef MULTI_TLB
86struct cpu_tlb_fns cpu_tlb;
87#endif
88#ifdef MULTI_USER
89struct cpu_user_fns cpu_user;
90#endif
91#ifdef MULTI_CACHE
92struct cpu_cache_fns cpu_cache;
93#endif
94
95unsigned char aux_device_present;
96
97char elf_platform[ELF_PLATFORM_SIZE];
98EXPORT_SYMBOL(elf_platform);
99
100unsigned long phys_initrd_start __initdata = 0;
101unsigned long phys_initrd_size __initdata = 0;
102
103static struct meminfo meminfo __initdata = { 0, };
104static const char *cpu_name;
105static const char *machine_name;
106static char command_line[COMMAND_LINE_SIZE];
107
108static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
109static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
110#define ENDIANNESS ((char)endian_test.l)
111
112DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data);
113
114
115
116
117static struct resource mem_res[] = {
118 { "Video RAM", 0, 0, IORESOURCE_MEM },
119 { "Kernel text", 0, 0, IORESOURCE_MEM },
120 { "Kernel data", 0, 0, IORESOURCE_MEM }
121};
122
123#define video_ram mem_res[0]
124#define kernel_code mem_res[1]
125#define kernel_data mem_res[2]
126
127static struct resource io_res[] = {
128 { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY },
129 { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY },
130 { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY }
131};
132
133#define lp0 io_res[0]
134#define lp1 io_res[1]
135#define lp2 io_res[2]
136
137static const char *cache_types[16] = {
138 "write-through",
139 "write-back",
140 "write-back",
141 "undefined 3",
142 "undefined 4",
143 "undefined 5",
144 "write-back",
145 "write-back",
146 "undefined 8",
147 "undefined 9",
148 "undefined 10",
149 "undefined 11",
150 "undefined 12",
151 "undefined 13",
152 "write-back",
153 "undefined 15",
154};
155
156static const char *cache_clean[16] = {
157 "not required",
158 "read-block",
159 "cp15 c7 ops",
160 "undefined 3",
161 "undefined 4",
162 "undefined 5",
163 "cp15 c7 ops",
164 "cp15 c7 ops",
165 "undefined 8",
166 "undefined 9",
167 "undefined 10",
168 "undefined 11",
169 "undefined 12",
170 "undefined 13",
171 "cp15 c7 ops",
172 "undefined 15",
173};
174
175static const char *cache_lockdown[16] = {
176 "not supported",
177 "not supported",
178 "not supported",
179 "undefined 3",
180 "undefined 4",
181 "undefined 5",
182 "format A",
183 "format B",
184 "undefined 8",
185 "undefined 9",
186 "undefined 10",
187 "undefined 11",
188 "undefined 12",
189 "undefined 13",
190 "format C",
191 "undefined 15",
192};
193
194static const char *proc_arch[] = {
195 "undefined/unknown",
196 "3",
197 "4",
198 "4T",
199 "5",
200 "5T",
201 "5TE",
202 "5TEJ",
203 "6TEJ",
204 "?(10)",
205 "?(11)",
206 "?(12)",
207 "?(13)",
208 "?(14)",
209 "?(15)",
210 "?(16)",
211 "?(17)",
212};
213
214#define CACHE_TYPE(x) (((x) >> 25) & 15)
215#define CACHE_S(x) ((x) & (1 << 24))
216#define CACHE_DSIZE(x) (((x) >> 12) & 4095)
217#define CACHE_ISIZE(x) ((x) & 4095)
218
219#define CACHE_SIZE(y) (((y) >> 6) & 7)
220#define CACHE_ASSOC(y) (((y) >> 3) & 7)
221#define CACHE_M(y) ((y) & (1 << 2))
222#define CACHE_LINE(y) ((y) & 3)
223
224static inline void dump_cache(const char *prefix, int cpu, unsigned int cache)
225{
226 unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
227
228 printk("CPU%u: %s: %d bytes, associativity %d, %d byte lines, %d sets\n",
229 cpu, prefix,
230 mult << (8 + CACHE_SIZE(cache)),
231 (mult << CACHE_ASSOC(cache)) >> 1,
232 8 << CACHE_LINE(cache),
233 1 << (6 + CACHE_SIZE(cache) - CACHE_ASSOC(cache) -
234 CACHE_LINE(cache)));
235}
236
237static void __init dump_cpu_info(int cpu)
238{
239 unsigned int info = read_cpuid(CPUID_CACHETYPE);
240
241 if (info != processor_id) {
242 printk("CPU%u: D %s %s cache\n", cpu, cache_is_vivt() ? "VIVT" : "VIPT",
243 cache_types[CACHE_TYPE(info)]);
244 if (CACHE_S(info)) {
245 dump_cache("I cache", cpu, CACHE_ISIZE(info));
246 dump_cache("D cache", cpu, CACHE_DSIZE(info));
247 } else {
248 dump_cache("cache", cpu, CACHE_ISIZE(info));
249 }
250 }
251}
252
253int cpu_architecture(void)
254{
255 int cpu_arch;
256
257 if ((processor_id & 0x0000f000) == 0) {
258 cpu_arch = CPU_ARCH_UNKNOWN;
259 } else if ((processor_id & 0x0000f000) == 0x00007000) {
260 cpu_arch = (processor_id & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
261 } else {
262 cpu_arch = (processor_id >> 16) & 7;
263 if (cpu_arch)
264 cpu_arch += CPU_ARCH_ARMv3;
265 }
266
267 return cpu_arch;
268}
269
270
271
272
273
274extern struct proc_info_list *lookup_processor_type(void);
275extern struct machine_desc *lookup_machine_type(unsigned int);
276
277static void __init setup_processor(void)
278{
279 struct proc_info_list *list;
280
281
282
283
284
285
286 list = lookup_processor_type();
287 if (!list) {
288 printk("CPU configuration botched (ID %08x), unable "
289 "to continue.\n", processor_id);
290 while (1);
291 }
292
293 cpu_name = list->cpu_name;
294
295#ifdef MULTI_CPU
296 processor = *list->proc;
297#endif
298#ifdef MULTI_TLB
299 cpu_tlb = *list->tlb;
300#endif
301#ifdef MULTI_USER
302 cpu_user = *list->user;
303#endif
304#ifdef MULTI_CACHE
305 cpu_cache = *list->cache;
306#endif
307
308 printk("CPU: %s [%08x] revision %d (ARMv%s)\n",
309 cpu_name, processor_id, (int)processor_id & 15,
310 proc_arch[cpu_architecture()]);
311
312 dump_cpu_info(smp_processor_id());
313
314 sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
315 sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
316 elf_hwcap = list->elf_hwcap;
317
318 cpu_proc_init();
319}
320
321static struct machine_desc * __init setup_machine(unsigned int nr)
322{
323 struct machine_desc *list;
324
325
326
327
328 list = lookup_machine_type(nr);
329 if (!list) {
330 printk("Machine configuration botched (nr %d), unable "
331 "to continue.\n", nr);
332 while (1);
333 }
334
335 printk("Machine: %s\n", list->name);
336
337 return list;
338}
339
340static void __init early_initrd(char **p)
341{
342 unsigned long start, size;
343
344 start = memparse(*p, p);
345 if (**p == ',') {
346 size = memparse((*p) + 1, p);
347
348 phys_initrd_start = start;
349 phys_initrd_size = size;
350 }
351}
352__early_param("initrd=", early_initrd);
353
354
355
356
357
358static void __init early_mem(char **p)
359{
360 static int usermem __initdata = 0;
361 unsigned long size, start;
362
363
364
365
366
367
368 if (usermem == 0) {
369 usermem = 1;
370 meminfo.nr_banks = 0;
371 }
372
373 start = PHYS_OFFSET;
374 size = memparse(*p, p);
375 if (**p == '@')
376 start = memparse(*p + 1, p);
377
378 meminfo.bank[meminfo.nr_banks].start = start;
379 meminfo.bank[meminfo.nr_banks].size = size;
380 meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(start);
381 meminfo.nr_banks += 1;
382}
383__early_param("mem=", early_mem);
384
385
386
387
388static void __init parse_cmdline(char **cmdline_p, char *from)
389{
390 char c = ' ', *to = command_line;
391 int len = 0;
392
393 for (;;) {
394 if (c == ' ') {
395 extern struct early_params __early_begin, __early_end;
396 struct early_params *p;
397
398 for (p = &__early_begin; p < &__early_end; p++) {
399 int len = strlen(p->arg);
400
401 if (memcmp(from, p->arg, len) == 0) {
402 if (to != command_line)
403 to -= 1;
404 from += len;
405 p->fn(&from);
406
407 while (*from != ' ' && *from != '\0')
408 from++;
409 break;
410 }
411 }
412 }
413 c = *from++;
414 if (!c)
415 break;
416 if (COMMAND_LINE_SIZE <= ++len)
417 break;
418 *to++ = c;
419 }
420 *to = '\0';
421 *cmdline_p = command_line;
422}
423
424static void __init
425setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
426{
427#ifdef CONFIG_BLK_DEV_RAM
428 extern int rd_size, rd_image_start, rd_prompt, rd_doload;
429
430 rd_image_start = image_start;
431 rd_prompt = prompt;
432 rd_doload = doload;
433
434 if (rd_sz)
435 rd_size = rd_sz;
436#endif
437}
438
439static void __init
440request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
441{
442 struct resource *res;
443 int i;
444
445 kernel_code.start = virt_to_phys(&_text);
446 kernel_code.end = virt_to_phys(&_etext - 1);
447 kernel_data.start = virt_to_phys(&__data_start);
448 kernel_data.end = virt_to_phys(&_end - 1);
449
450 for (i = 0; i < mi->nr_banks; i++) {
451 unsigned long virt_start, virt_end;
452
453 if (mi->bank[i].size == 0)
454 continue;
455
456 virt_start = __phys_to_virt(mi->bank[i].start);
457 virt_end = virt_start + mi->bank[i].size - 1;
458
459 res = alloc_bootmem_low(sizeof(*res));
460 res->name = "System RAM";
461 res->start = __virt_to_phys(virt_start);
462 res->end = __virt_to_phys(virt_end);
463 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
464
465 request_resource(&iomem_resource, res);
466
467 if (kernel_code.start >= res->start &&
468 kernel_code.end <= res->end)
469 request_resource(res, &kernel_code);
470 if (kernel_data.start >= res->start &&
471 kernel_data.end <= res->end)
472 request_resource(res, &kernel_data);
473 }
474
475 if (mdesc->video_start) {
476 video_ram.start = mdesc->video_start;
477 video_ram.end = mdesc->video_end;
478 request_resource(&iomem_resource, &video_ram);
479 }
480
481
482
483
484
485 if (mdesc->reserve_lp0)
486 request_resource(&ioport_resource, &lp0);
487 if (mdesc->reserve_lp1)
488 request_resource(&ioport_resource, &lp1);
489 if (mdesc->reserve_lp2)
490 request_resource(&ioport_resource, &lp2);
491}
492
493
494
495
496
497
498
499
500
501
502
503static int __init parse_tag_core(const struct tag *tag)
504{
505 if (tag->hdr.size > 2) {
506 if ((tag->u.core.flags & 1) == 0)
507 root_mountflags &= ~MS_RDONLY;
508 ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
509 }
510 return 0;
511}
512
513__tagtable(ATAG_CORE, parse_tag_core);
514
515static int __init parse_tag_mem32(const struct tag *tag)
516{
517 if (meminfo.nr_banks >= NR_BANKS) {
518 printk(KERN_WARNING
519 "Ignoring memory bank 0x%08x size %dKB\n",
520 tag->u.mem.start, tag->u.mem.size / 1024);
521 return -EINVAL;
522 }
523 meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start;
524 meminfo.bank[meminfo.nr_banks].size = tag->u.mem.size;
525 meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(tag->u.mem.start);
526 meminfo.nr_banks += 1;
527
528 return 0;
529}
530
531__tagtable(ATAG_MEM, parse_tag_mem32);
532
533#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
534struct screen_info screen_info = {
535 .orig_video_lines = 30,
536 .orig_video_cols = 80,
537 .orig_video_mode = 0,
538 .orig_video_ega_bx = 0,
539 .orig_video_isVGA = 1,
540 .orig_video_points = 8
541};
542
543static int __init parse_tag_videotext(const struct tag *tag)
544{
545 screen_info.orig_x = tag->u.videotext.x;
546 screen_info.orig_y = tag->u.videotext.y;
547 screen_info.orig_video_page = tag->u.videotext.video_page;
548 screen_info.orig_video_mode = tag->u.videotext.video_mode;
549 screen_info.orig_video_cols = tag->u.videotext.video_cols;
550 screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
551 screen_info.orig_video_lines = tag->u.videotext.video_lines;
552 screen_info.orig_video_isVGA = tag->u.videotext.video_isvga;
553 screen_info.orig_video_points = tag->u.videotext.video_points;
554 return 0;
555}
556
557__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
558#endif
559
560static int __init parse_tag_ramdisk(const struct tag *tag)
561{
562 setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
563 (tag->u.ramdisk.flags & 2) == 0,
564 tag->u.ramdisk.start, tag->u.ramdisk.size);
565 return 0;
566}
567
568__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
569
570static int __init parse_tag_initrd(const struct tag *tag)
571{
572 printk(KERN_WARNING "ATAG_INITRD is deprecated; "
573 "please update your bootloader.\n");
574 phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
575 phys_initrd_size = tag->u.initrd.size;
576 return 0;
577}
578
579__tagtable(ATAG_INITRD, parse_tag_initrd);
580
581static int __init parse_tag_initrd2(const struct tag *tag)
582{
583 phys_initrd_start = tag->u.initrd.start;
584 phys_initrd_size = tag->u.initrd.size;
585 return 0;
586}
587
588__tagtable(ATAG_INITRD2, parse_tag_initrd2);
589
590static int __init parse_tag_serialnr(const struct tag *tag)
591{
592 system_serial_low = tag->u.serialnr.low;
593 system_serial_high = tag->u.serialnr.high;
594 return 0;
595}
596
597__tagtable(ATAG_SERIAL, parse_tag_serialnr);
598
599static int __init parse_tag_revision(const struct tag *tag)
600{
601 system_rev = tag->u.revision.rev;
602 return 0;
603}
604
605__tagtable(ATAG_REVISION, parse_tag_revision);
606
607static int __init parse_tag_cmdline(const struct tag *tag)
608{
609 strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
610 return 0;
611}
612
613__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
614
615
616
617
618
619
620static int __init parse_tag(const struct tag *tag)
621{
622 extern struct tagtable __tagtable_begin, __tagtable_end;
623 struct tagtable *t;
624
625 for (t = &__tagtable_begin; t < &__tagtable_end; t++)
626 if (tag->hdr.tag == t->tag) {
627 t->parse(tag);
628 break;
629 }
630
631 return t < &__tagtable_end;
632}
633
634
635
636
637
638static void __init parse_tags(const struct tag *t)
639{
640 for (; t->hdr.size; t = tag_next(t))
641 if (!parse_tag(t))
642 printk(KERN_WARNING
643 "Ignoring unrecognised tag 0x%08x\n",
644 t->hdr.tag);
645}
646
647
648
649
650static struct init_tags {
651 struct tag_header hdr1;
652 struct tag_core core;
653 struct tag_header hdr2;
654 struct tag_mem32 mem;
655 struct tag_header hdr3;
656} init_tags __initdata = {
657 { tag_size(tag_core), ATAG_CORE },
658 { 1, PAGE_SIZE, 0xff },
659 { tag_size(tag_mem32), ATAG_MEM },
660 { MEM_SIZE, PHYS_OFFSET },
661 { 0, ATAG_NONE }
662};
663
664static void (*init_machine)(void) __initdata;
665
666static int __init customize_machine(void)
667{
668
669 if (init_machine)
670 init_machine();
671 return 0;
672}
673arch_initcall(customize_machine);
674
675void __init setup_arch(char **cmdline_p)
676{
677 struct tag *tags = (struct tag *)&init_tags;
678 struct machine_desc *mdesc;
679 char *from = default_command_line;
680
681 setup_processor();
682 mdesc = setup_machine(machine_arch_type);
683 machine_name = mdesc->name;
684
685 if (mdesc->soft_reboot)
686 reboot_setup("s");
687
688 if (mdesc->param_offset)
689 tags = phys_to_virt(mdesc->param_offset);
690
691
692
693
694
695 if (tags->hdr.tag != ATAG_CORE)
696 convert_to_tag_list(tags);
697 if (tags->hdr.tag != ATAG_CORE)
698 tags = (struct tag *)&init_tags;
699
700 if (mdesc->fixup)
701 mdesc->fixup(mdesc, tags, &from, &meminfo);
702
703 if (tags->hdr.tag == ATAG_CORE) {
704 if (meminfo.nr_banks != 0)
705 squash_mem_tags(tags);
706 parse_tags(tags);
707 }
708
709 init_mm.start_code = (unsigned long) &_text;
710 init_mm.end_code = (unsigned long) &_etext;
711 init_mm.end_data = (unsigned long) &_edata;
712 init_mm.brk = (unsigned long) &_end;
713
714 memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
715 saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
716 parse_cmdline(cmdline_p, from);
717 paging_init(&meminfo, mdesc);
718 request_standard_resources(&meminfo, mdesc);
719
720
721
722
723 init_arch_irq = mdesc->init_irq;
724 system_timer = mdesc->timer;
725 init_machine = mdesc->init_machine;
726
727#ifdef CONFIG_VT
728#if defined(CONFIG_VGA_CONSOLE)
729 conswitchp = &vga_con;
730#elif defined(CONFIG_DUMMY_CONSOLE)
731 conswitchp = &dummy_con;
732#endif
733#endif
734}
735
736
737static int __init topology_init(void)
738{
739 int cpu;
740
741 for_each_cpu(cpu)
742 register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL);
743
744 return 0;
745}
746
747subsys_initcall(topology_init);
748
749static const char *hwcap_str[] = {
750 "swp",
751 "half",
752 "thumb",
753 "26bit",
754 "fastmult",
755 "fpa",
756 "vfp",
757 "edsp",
758 "java",
759 NULL
760};
761
762static void
763c_show_cache(struct seq_file *m, const char *type, unsigned int cache)
764{
765 unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
766
767 seq_printf(m, "%s size\t\t: %d\n"
768 "%s assoc\t\t: %d\n"
769 "%s line length\t: %d\n"
770 "%s sets\t\t: %d\n",
771 type, mult << (8 + CACHE_SIZE(cache)),
772 type, (mult << CACHE_ASSOC(cache)) >> 1,
773 type, 8 << CACHE_LINE(cache),
774 type, 1 << (6 + CACHE_SIZE(cache) - CACHE_ASSOC(cache) -
775 CACHE_LINE(cache)));
776}
777
778static int c_show(struct seq_file *m, void *v)
779{
780 int i;
781
782 seq_printf(m, "Processor\t: %s rev %d (%s)\n",
783 cpu_name, (int)processor_id & 15, elf_platform);
784
785#if defined(CONFIG_SMP)
786 for_each_online_cpu(i) {
787 seq_printf(m, "Processor\t: %d\n", i);
788 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
789 per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
790 (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
791 }
792#else
793 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
794 loops_per_jiffy / (500000/HZ),
795 (loops_per_jiffy / (5000/HZ)) % 100);
796#endif
797
798
799 seq_puts(m, "Features\t: ");
800
801 for (i = 0; hwcap_str[i]; i++)
802 if (elf_hwcap & (1 << i))
803 seq_printf(m, "%s ", hwcap_str[i]);
804
805 seq_printf(m, "\nCPU implementer\t: 0x%02x\n", processor_id >> 24);
806 seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
807
808 if ((processor_id & 0x0000f000) == 0x00000000) {
809
810 seq_printf(m, "CPU part\t\t: %07x\n", processor_id >> 4);
811 } else {
812 if ((processor_id & 0x0000f000) == 0x00007000) {
813
814 seq_printf(m, "CPU variant\t: 0x%02x\n",
815 (processor_id >> 16) & 127);
816 } else {
817
818 seq_printf(m, "CPU variant\t: 0x%x\n",
819 (processor_id >> 20) & 15);
820 }
821 seq_printf(m, "CPU part\t: 0x%03x\n",
822 (processor_id >> 4) & 0xfff);
823 }
824 seq_printf(m, "CPU revision\t: %d\n", processor_id & 15);
825
826 {
827 unsigned int cache_info = read_cpuid(CPUID_CACHETYPE);
828 if (cache_info != processor_id) {
829 seq_printf(m, "Cache type\t: %s\n"
830 "Cache clean\t: %s\n"
831 "Cache lockdown\t: %s\n"
832 "Cache format\t: %s\n",
833 cache_types[CACHE_TYPE(cache_info)],
834 cache_clean[CACHE_TYPE(cache_info)],
835 cache_lockdown[CACHE_TYPE(cache_info)],
836 CACHE_S(cache_info) ? "Harvard" : "Unified");
837
838 if (CACHE_S(cache_info)) {
839 c_show_cache(m, "I", CACHE_ISIZE(cache_info));
840 c_show_cache(m, "D", CACHE_DSIZE(cache_info));
841 } else {
842 c_show_cache(m, "Cache", CACHE_ISIZE(cache_info));
843 }
844 }
845 }
846
847 seq_puts(m, "\n");
848
849 seq_printf(m, "Hardware\t: %s\n", machine_name);
850 seq_printf(m, "Revision\t: %04x\n", system_rev);
851 seq_printf(m, "Serial\t\t: %08x%08x\n",
852 system_serial_high, system_serial_low);
853
854 return 0;
855}
856
857static void *c_start(struct seq_file *m, loff_t *pos)
858{
859 return *pos < 1 ? (void *)1 : NULL;
860}
861
862static void *c_next(struct seq_file *m, void *v, loff_t *pos)
863{
864 ++*pos;
865 return NULL;
866}
867
868static void c_stop(struct seq_file *m, void *v)
869{
870}
871
872struct seq_operations cpuinfo_op = {
873 .start = c_start,
874 .next = c_next,
875 .stop = c_stop,
876 .show = c_show
877};
878