setup.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:19k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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