setup.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:17k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/x86-64/kernel/setup.c
  3.  *
  4.  *  Copyright (C) 1995  Linus Torvalds
  5.  *
  6.  *  Nov 2001 Dave Jones <davej@suse.de>
  7.  *  Forked from i386 setup code.
  8.  */
  9. /*
  10.  * This file handles the architecture-dependent parts of initialization
  11.  */
  12. #include <linux/errno.h>
  13. #include <linux/sched.h>
  14. #include <linux/kernel.h>
  15. #include <linux/mm.h>
  16. #include <linux/stddef.h>
  17. #include <linux/unistd.h>
  18. #include <linux/ptrace.h>
  19. #include <linux/slab.h>
  20. #include <linux/user.h>
  21. #include <linux/a.out.h>
  22. #include <linux/tty.h>
  23. #include <linux/ioport.h>
  24. #include <linux/delay.h>
  25. #include <linux/config.h>
  26. #include <linux/init.h>
  27. #include <linux/blk.h>
  28. #include <linux/highmem.h>
  29. #include <linux/bootmem.h>
  30. #include <asm/processor.h>
  31. #include <linux/console.h>
  32. #include <linux/seq_file.h>
  33. #include <asm/mtrr.h>
  34. #include <asm/uaccess.h>
  35. #include <asm/system.h>
  36. #include <asm/io.h>
  37. #include <asm/smp.h>
  38. #include <asm/msr.h>
  39. #include <asm/desc.h>
  40. #include <asm/e820.h>
  41. #include <asm/dma.h>
  42. #include <asm/mpspec.h>
  43. #include <asm/mmu_context.h>
  44. #include <asm/bootsetup.h>
  45. #include <asm/proto.h>
  46. /*
  47.  * Machine setup..
  48.  */
  49. struct cpuinfo_x86 boot_cpu_data = { 
  50. cpuid_level: -1, 
  51. };
  52. unsigned long mmu_cr4_features;
  53. /* For PCI or other memory-mapped resources */
  54. unsigned long pci_mem_start = 0x10000000;
  55. /*
  56.  * Setup options
  57.  */
  58. struct drive_info_struct { char dummy[32]; } drive_info;
  59. struct screen_info screen_info;
  60. struct sys_desc_table_struct {
  61. unsigned short length;
  62. unsigned char table[0];
  63. };
  64. struct e820map e820;
  65. unsigned char aux_device_present;
  66. extern int root_mountflags;
  67. extern char _text, _etext, _edata, _end;
  68. static int disable_x86_fxsr __initdata = 0;
  69. char command_line[COMMAND_LINE_SIZE];
  70. char saved_command_line[COMMAND_LINE_SIZE];
  71. struct resource standard_io_resources[] = {
  72. { "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
  73. { "pic1", 0x20, 0x3f, IORESOURCE_BUSY },
  74. { "timer", 0x40, 0x5f, IORESOURCE_BUSY },
  75. { "keyboard", 0x60, 0x6f, IORESOURCE_BUSY },
  76. { "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY },
  77. { "pic2", 0xa0, 0xbf, IORESOURCE_BUSY },
  78. { "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },
  79. { "fpu", 0xf0, 0xff, IORESOURCE_BUSY }
  80. };
  81. #define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
  82. struct resource code_resource = { "Kernel code", 0x100000, 0 };
  83. struct resource data_resource = { "Kernel data", 0, 0 };
  84. struct resource vram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_BUSY };
  85. /* System ROM resources */
  86. #define MAXROMS 6
  87. static struct resource rom_resources[MAXROMS] = {
  88. { "System ROM", 0xF0000, 0xFFFFF, IORESOURCE_BUSY },
  89. { "Video ROM", 0xc0000, 0xc7fff, IORESOURCE_BUSY }
  90. };
  91. #define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
  92. static void __init probe_roms(void)
  93. {
  94. int roms = 1;
  95. unsigned long base;
  96. unsigned char *romstart;
  97. request_resource(&iomem_resource, rom_resources+0);
  98. /* Video ROM is standard at C000:0000 - C7FF:0000, check signature */
  99. for (base = 0xC0000; base < 0xE0000; base += 2048) {
  100. romstart = bus_to_virt(base);
  101. if (!romsignature(romstart))
  102. continue;
  103. request_resource(&iomem_resource, rom_resources + roms);
  104. roms++;
  105. break;
  106. }
  107. /* Extension roms at C800:0000 - DFFF:0000 */
  108. for (base = 0xC8000; base < 0xE0000; base += 2048) {
  109. unsigned long length;
  110. romstart = bus_to_virt(base);
  111. if (!romsignature(romstart))
  112. continue;
  113. length = romstart[2] * 512;
  114. if (length) {
  115. unsigned int i;
  116. unsigned char chksum;
  117. chksum = 0;
  118. for (i = 0; i < length; i++)
  119. chksum += romstart[i];
  120. /* Good checksum? */
  121. if (!chksum) {
  122. rom_resources[roms].start = base;
  123. rom_resources[roms].end = base + length - 1;
  124. rom_resources[roms].name = "Extension ROM";
  125. rom_resources[roms].flags = IORESOURCE_BUSY;
  126. request_resource(&iomem_resource, rom_resources + roms);
  127. roms++;
  128. if (roms >= MAXROMS)
  129. return;
  130. }
  131. }
  132. }
  133. /* Final check for motherboard extension rom at E000:0000 */
  134. base = 0xE0000;
  135. romstart = bus_to_virt(base);
  136. if (romsignature(romstart)) {
  137. rom_resources[roms].start = base;
  138. rom_resources[roms].end = base + 65535;
  139. rom_resources[roms].name = "Extension ROM";
  140. rom_resources[roms].flags = IORESOURCE_BUSY;
  141. request_resource(&iomem_resource, rom_resources + roms);
  142. }
  143. }
  144. unsigned long start_pfn, end_pfn; 
  145. extern unsigned long table_start, table_end;
  146. #ifndef CONFIG_DISCONTIGMEM
  147. static void __init contig_initmem_init(void)
  148. {
  149. unsigned long bootmap_size, bootmap; 
  150. bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
  151. bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
  152. if (bootmap == -1L) 
  153. panic("Cannot find bootmem map of size %ldn",bootmap_size);
  154. bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
  155. e820_bootmem_free(&contig_page_data, 0, end_pfn << PAGE_SHIFT); 
  156. reserve_bootmem(bootmap, bootmap_size);
  157. }
  158. #endif
  159. void __init setup_arch(char **cmdline_p)
  160. {
  161. int i;
  162. unsigned long kernel_end; 
  163.   ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
  164.   drive_info = DRIVE_INFO;
  165.   screen_info = SCREEN_INFO;
  166. aux_device_present = AUX_DEVICE_INFO;
  167. #ifdef CONFIG_BLK_DEV_RAM
  168. rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
  169. rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
  170. rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
  171. #endif
  172. setup_memory_region();
  173. if (!MOUNT_ROOT_RDONLY)
  174. root_mountflags &= ~MS_RDONLY;
  175. init_mm.start_code = (unsigned long) &_text;
  176. init_mm.end_code = (unsigned long) &_etext;
  177. init_mm.end_data = (unsigned long) &_edata;
  178. init_mm.brk = (unsigned long) &_end;
  179. code_resource.start = virt_to_bus(&_text);
  180. code_resource.end = virt_to_bus(&_etext)-1;
  181. data_resource.start = virt_to_bus(&_etext);
  182. data_resource.end = virt_to_bus(&_edata)-1;
  183. parse_mem_cmdline(cmdline_p);
  184. e820_end_of_ram();
  185. init_memory_mapping(); 
  186. #ifdef CONFIG_BLK_DEV_INITRD
  187. if (LOADER_TYPE && INITRD_START) {
  188. if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) {
  189. initrd_start =
  190. INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
  191. initrd_end = initrd_start+INITRD_SIZE;
  192. }
  193. else {
  194. printk(KERN_ERR "initrd extends beyond end of memory "
  195.     "(0x%08lx > 0x%08lx)ndisabling initrdn",
  196.     (unsigned long)INITRD_START + INITRD_SIZE,
  197.     (unsigned long)(end_pfn << PAGE_SHIFT));
  198. initrd_start = 0;
  199. }
  200. }
  201. #endif
  202. #ifdef CONFIG_DISCONTIGMEM
  203. numa_initmem_init(0, end_pfn); 
  204. #else
  205. contig_initmem_init(); 
  206. #endif
  207. /* Reserve direct mapping */
  208. reserve_bootmem_generic(table_start << PAGE_SHIFT, 
  209. (table_end - table_start) << PAGE_SHIFT);
  210. #ifdef CONFIG_BLK_DEV_INITRD
  211. if (initrd_start) 
  212. reserve_bootmem_generic(INITRD_START, INITRD_SIZE);
  213. #endif
  214. /* Reserve BIOS data page. Some things still need it */
  215. reserve_bootmem_generic(0, PAGE_SIZE);
  216. #ifdef CONFIG_SMP
  217. /*
  218.  * But first pinch a few for the stack/trampoline stuff
  219.  * FIXME: Don't need the extra page at 4K, but need to fix
  220.  * trampoline before removing it. (see the GDT stuff)
  221.  */
  222. reserve_bootmem_generic(PAGE_SIZE, PAGE_SIZE); 
  223. /* Reserve SMP trampoline */
  224. reserve_bootmem_generic(0x6000, PAGE_SIZE);
  225. #endif
  226. /* Reserve Kernel */
  227. kernel_end = round_up(__pa_symbol(&_end), PAGE_SIZE);
  228. reserve_bootmem_generic(HIGH_MEMORY, kernel_end - HIGH_MEMORY);
  229. #ifdef CONFIG_X86_LOCAL_APIC
  230. /*
  231.  * Find and reserve possible boot-time SMP configuration:
  232.  */
  233. find_smp_config();
  234. #endif
  235. #ifdef CONFIG_SMP
  236. /* AP processor realmode stacks in low memory*/
  237. smp_alloc_memory();
  238. #endif
  239. paging_init();
  240. #ifdef CONFIG_X86_LOCAL_APIC
  241. /*
  242.  * get boot-time SMP configuration:
  243.  */
  244. if (smp_found_config)
  245. get_smp_config();
  246. init_apic_mappings();
  247. #endif
  248. /*
  249.  * Request address space for all standard RAM and ROM resources
  250.  * and also for regions reported as reserved by the e820.
  251.  */
  252. probe_roms();
  253. e820_reserve_resources(); 
  254. request_resource(&iomem_resource, &vram_resource);
  255. /* request I/O space for devices used on all i[345]86 PCs */
  256. for (i = 0; i < STANDARD_IO_RESOURCES; i++)
  257. request_resource(&ioport_resource, standard_io_resources+i);
  258. /* We put PCI memory up to make sure VALID_PAGE with DISCONTIGMEM
  259.    never returns true for it */ 
  260. /* Tell the PCI layer not to allocate too close to the RAM area.. */
  261. pci_mem_start = IOMAP_START;
  262. #ifdef CONFIG_GART_IOMMU
  263. iommu_hole_init();
  264. #endif
  265. #ifdef CONFIG_VT
  266. #if defined(CONFIG_VGA_CONSOLE)
  267. conswitchp = &vga_con;
  268. #elif defined(CONFIG_DUMMY_CONSOLE)
  269. conswitchp = &dummy_con;
  270. #endif
  271. #endif
  272. num_mappedpages = end_pfn;
  273. }
  274. #ifndef CONFIG_X86_TSC
  275. static int tsc_disable __initdata = 0;
  276. static int __init tsc_setup(char *str)
  277. {
  278. tsc_disable = 1;
  279. return 1;
  280. }
  281. __setup("notsc", tsc_setup);
  282. #endif
  283. static int __init get_model_name(struct cpuinfo_x86 *c)
  284. {
  285. unsigned int *v;
  286. if (cpuid_eax(0x80000000) < 0x80000004)
  287. return 0;
  288. v = (unsigned int *) c->x86_model_id;
  289. cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
  290. cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
  291. cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
  292. c->x86_model_id[48] = 0;
  293. return 1;
  294. }
  295. static void __init display_cacheinfo(struct cpuinfo_x86 *c)
  296. {
  297. unsigned int n, dummy, ecx, edx, eax, ebx, eax_2, ebx_2, ecx_2;
  298. n = cpuid_eax(0x80000000);
  299. if (n >= 0x80000005) {
  300. if (n >= 0x80000006) 
  301. cpuid(0x80000006, &eax_2, &ebx_2, &ecx_2, &dummy); 
  302. cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
  303. printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line/%d way), D cache %dK (%d bytes/line/%d way)n",
  304.        edx>>24, edx&0xFF, (edx>>16)&0xff, 
  305.        ecx>>24, ecx&0xFF, (ecx>>16)&0xff);
  306. c->x86_cache_size=(ecx>>24)+(edx>>24);
  307. if (n >= 0x80000006) {
  308. printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line/%d way)n",
  309.        ecx_2>>16, ecx_2&0xFF, (ecx_2>>12)&0xf);
  310. c->x86_cache_size = ecx_2 >> 16;
  311. }
  312. printk(KERN_INFO "CPU: DTLB L1 %d 4K %d 2MB L2: %d 4K %d 2MBn",
  313.        (ebx>>16)&0xff, (eax>>16)&0xff, 
  314.        (ebx_2>>16)&0xfff, (eax_2>>16)&0xfff);
  315. printk(KERN_INFO "CPU: ITLB L1 %d 4K %d 2MB L2: %d 4K %d 2MBn",
  316.        ebx&0xff, (eax)&0xff, 
  317.        (ebx_2)&0xfff, (eax_2)&0xfff);
  318. c->x86_tlbsize = ((ebx>>16)&0xff) + ((ebx_2>>16)&0xfff) + 
  319. (ebx&0xff) + ((ebx_2)&0xfff);
  320. }
  321. }
  322. static int __init init_amd(struct cpuinfo_x86 *c)
  323. {
  324. int r;
  325. /* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
  326.    3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
  327. clear_bit(0*32+31, &c->x86_capability);
  328. r = get_model_name(c);
  329. if (!r) { 
  330. switch (c->x86) { 
  331. case 15:
  332. /* Should distingush Models here, but this is only
  333.    a fallback anyways. */
  334. strcpy(c->x86_model_id, "Hammer");
  335. break; 
  336. display_cacheinfo(c);
  337. return r;
  338. }
  339. void __init get_cpu_vendor(struct cpuinfo_x86 *c)
  340. {
  341. char *v = c->x86_vendor_id;
  342. if (!strcmp(v, "AuthenticAMD"))
  343. c->x86_vendor = X86_VENDOR_AMD;
  344. else
  345. c->x86_vendor = X86_VENDOR_UNKNOWN;
  346. }
  347. struct cpu_model_info {
  348. int vendor;
  349. int family;
  350. char *model_names[16];
  351. };
  352. int __init x86_fxsr_setup(char * s)
  353. {
  354. disable_x86_fxsr = 1;
  355. return 1;
  356. }
  357. __setup("nofxsr", x86_fxsr_setup);
  358. /*
  359.  * This does the hard work of actually picking apart the CPU stuff...
  360.  */
  361. void __init identify_cpu(struct cpuinfo_x86 *c)
  362. {
  363. int junk, i;
  364. u32 xlvl, tfms;
  365. c->loops_per_jiffy = loops_per_jiffy;
  366. c->x86_cache_size = -1;
  367. c->x86_vendor = X86_VENDOR_UNKNOWN;
  368. c->x86_model = c->x86_mask = 0; /* So far unknown... */
  369. c->x86_vendor_id[0] = ''; /* Unset */
  370. c->x86_model_id[0] = '';  /* Unset */
  371. memset(&c->x86_capability, 0, sizeof c->x86_capability);
  372. /* Get vendor name */
  373. cpuid(0x00000000, &c->cpuid_level,
  374.       (int *)&c->x86_vendor_id[0],
  375.       (int *)&c->x86_vendor_id[8],
  376.       (int *)&c->x86_vendor_id[4]);
  377. get_cpu_vendor(c);
  378. /* Initialize the standard set of capabilities */
  379. /* Note that the vendor-specific code below might override */
  380. /* Intel-defined flags: level 0x00000001 */
  381. if ( c->cpuid_level >= 0x00000001 ) {
  382. __u32 misc;
  383. cpuid(0x00000001, &tfms, &misc, &junk,
  384.       &c->x86_capability[0]);
  385. c->x86 = (tfms >> 8) & 15;
  386. if (c->x86 == 0xf)
  387. c->x86 += (tfms >> 20) & 0xff;
  388. c->x86_model = (tfms >> 4) & 15;
  389. if (c->x86_model == 0xf)
  390. c->x86_model += ((tfms >> 16) & 0xF) << 4; 
  391. c->x86_mask = tfms & 15;
  392. if (c->x86_capability[0] & (1<<19)) 
  393. c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
  394. } else {
  395. /* Have CPUID level 0 only - unheard of */
  396. c->x86 = 4;
  397. }
  398. /* AMD-defined flags: level 0x80000001 */
  399. xlvl = cpuid_eax(0x80000000);
  400. if ( (xlvl & 0xffff0000) == 0x80000000 ) {
  401. if ( xlvl >= 0x80000001 )
  402. c->x86_capability[1] = cpuid_edx(0x80000001);
  403. if ( xlvl >= 0x80000004 )
  404. get_model_name(c); /* Default name */
  405. }
  406. /* Transmeta-defined flags: level 0x80860001 */
  407. xlvl = cpuid_eax(0x80860000);
  408. if ( (xlvl & 0xffff0000) == 0x80860000 ) {
  409. if (  xlvl >= 0x80860001 )
  410. c->x86_capability[2] = cpuid_edx(0x80860001);
  411. }
  412. /*
  413.  * Vendor-specific initialization.  In this section we
  414.  * canonicalize the feature flags, meaning if there are
  415.  * features a certain CPU supports which CPUID doesn't
  416.  * tell us, CPUID claiming incorrect flags, or other bugs,
  417.  * we handle them here.
  418.  *
  419.  * At the end of this section, c->x86_capability better
  420.  * indicate the features this CPU genuinely supports!
  421.  */
  422. switch ( c->x86_vendor ) {
  423. case X86_VENDOR_AMD:
  424. init_amd(c);
  425. break;
  426. case X86_VENDOR_UNKNOWN:
  427. default:
  428. /* Not much we can do here... */
  429. break;
  430. }
  431. /*
  432.  * The vendor-specific functions might have changed features.  Now
  433.  * we do "generic changes."
  434.  */
  435. /* TSC disabled? */
  436. #ifndef CONFIG_X86_TSC
  437. if ( tsc_disable )
  438. clear_bit(X86_FEATURE_TSC, &c->x86_capability);
  439. #endif
  440. /* FXSR disabled? */
  441. if (disable_x86_fxsr) {
  442. clear_bit(X86_FEATURE_FXSR, &c->x86_capability);
  443. clear_bit(X86_FEATURE_XMM, &c->x86_capability);
  444. }
  445. /*
  446.  * On SMP, boot_cpu_data holds the common feature set between
  447.  * all CPUs; so make sure that we indicate which features are
  448.  * common between the CPUs.  The first time this routine gets
  449.  * executed, c == &boot_cpu_data.
  450.  */
  451. if ( c != &boot_cpu_data ) {
  452. /* AND the already accumulated flags with these */
  453. for ( i = 0 ; i < NCAPINTS ; i++ )
  454. boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
  455. }
  456. #ifdef CONFIG_MCE
  457. mcheck_init(c);
  458. #endif
  459. }
  460.  
  461. void __init print_cpu_info(struct cpuinfo_x86 *c)
  462. {
  463. if (c->x86_model_id[0])
  464. printk("%s", c->x86_model_id);
  465. if (c->x86_mask || c->cpuid_level >= 0) 
  466. printk(" stepping %02xn", c->x86_mask);
  467. else
  468. printk("n");
  469. }
  470. /*
  471.  * Get CPU information for use by the procfs.
  472.  */
  473. static int show_cpuinfo(struct seq_file *m, void *v)
  474. {
  475. struct cpuinfo_x86 *c = v;
  476. /* 
  477.  * These flag bits must match the definitions in <asm/cpufeature.h>.
  478.  * NULL means this bit is undefined or reserved; either way it doesn't
  479.  * have meaning as far as Linux is concerned.  Note that it's important
  480.  * to realize there is a difference between this table and CPUID -- if
  481.  * applications want to get the raw CPUID data, they should access
  482.  * /dev/cpu/<cpu_nr>/cpuid instead.
  483.  */
  484. static char *x86_cap_flags[] = {
  485. /* Intel-defined */
  486.         "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
  487.         "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
  488.         "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
  489.         "fxsr", "sse", "sse2", "ss", NULL, "tm", "ia64", NULL,
  490. /* AMD-defined */
  491. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  492. NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
  493. NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL,
  494. NULL, NULL, NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
  495. /* Transmeta-defined */
  496. "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
  497. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  498. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  499. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  500. /* Other (Linux-defined) */
  501. "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", NULL, NULL, NULL, NULL,
  502. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  503. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  504. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  505. };
  506. #ifdef CONFIG_SMP
  507. if (!(cpu_online_map & (1<<(c-cpu_data))))
  508. return 0;
  509. #endif
  510. seq_printf(m,"processort: %un"
  511.      "vendor_idt: %sn"
  512.      "cpu familyt: %dn"
  513.      "modeltt: %dn"
  514.      "model namet: %sn",
  515.      (unsigned)(c-cpu_data),
  516.      c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
  517.      c->x86,
  518.      (int)c->x86_model,
  519.      c->x86_model_id[0] ? c->x86_model_id : "unknown");
  520. if (c->x86_mask || c->cpuid_level >= 0)
  521. seq_printf(m, "steppingt: %dn", c->x86_mask);
  522. else
  523. seq_printf(m, "steppingt: unknownn");
  524. if ( test_bit(X86_FEATURE_TSC, &c->x86_capability) ) {
  525. seq_printf(m, "cpu MHztt: %u.%03un",
  526.      cpu_khz / 1000, (cpu_khz % 1000));
  527. }
  528. seq_printf(m, "cache sizet: %d KBn", c->x86_cache_size);
  529. seq_printf(m,
  530.         "fputt: yesn"
  531.         "fpu_exceptiont: yesn"
  532.         "cpuid levelt: %dn"
  533.         "wptt: yesn"
  534.         "flagstt:",
  535.    c->cpuid_level);
  536. int i; 
  537. for ( i = 0 ; i < 32*NCAPINTS ; i++ )
  538. if ( test_bit(i, &c->x86_capability) &&
  539.      x86_cap_flags[i] != NULL )
  540. seq_printf(m, " %s", x86_cap_flags[i]);
  541. }
  542. seq_printf(m, "nbogomipst: %lu.%02lun",
  543.    c->loops_per_jiffy/(500000/HZ),
  544.    (c->loops_per_jiffy/(5000/HZ)) % 100);
  545. if (c->x86_tlbsize > 0) 
  546. seq_printf(m, "TLB sizet: %d 4K pagesn", c->x86_tlbsize);
  547. seq_printf(m, "clflush sizet: %dn", c->x86_clflush_size);
  548. seq_printf(m, "n"); 
  549. return 0;
  550. }
  551. static void *c_start(struct seq_file *m, loff_t *pos)
  552. {
  553. return *pos < NR_CPUS ? cpu_data + *pos : NULL;
  554. }
  555. static void *c_next(struct seq_file *m, void *v, loff_t *pos)
  556. {
  557. ++*pos;
  558. return c_start(m, pos);
  559. }
  560. static void c_stop(struct seq_file *m, void *v)
  561. {
  562. }
  563. struct seq_operations cpuinfo_op = {
  564. start: c_start,
  565. next: c_next,
  566. stop: c_stop,
  567. show: show_cpuinfo,
  568. };