1 /* 2 * arch/s390/kernel/processor.c 3 * 4 * Copyright IBM Corp. 2008 5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 6 */ 7 8 #define KMSG_COMPONENT "cpu" 9 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10 11 #include <linux/kernel.h> 12 #include <linux/init.h> 13 #include <linux/smp.h> 14 #include <linux/seq_file.h> 15 #include <linux/delay.h> 16 17 #include <asm/elf.h> 18 #include <asm/lowcore.h> 19 #include <asm/param.h> 20 21 void __cpuinit print_cpu_info(void) 22 { 23 pr_info("Processor %d started, address %d, identification %06X\n", 24 S390_lowcore.cpu_nr, S390_lowcore.cpu_addr, 25 S390_lowcore.cpu_id.ident); 26 } 27 28 /* 29 * show_cpuinfo - Get information on one CPU for use by procfs. 30 */ 31 32 static int show_cpuinfo(struct seq_file *m, void *v) 33 { 34 static const char *hwcap_str[10] = { 35 "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", 36 "edat", "etf3eh", "highgprs" 37 }; 38 struct _lowcore *lc; 39 unsigned long n = (unsigned long) v - 1; 40 int i; 41 42 s390_adjust_jiffies(); 43 preempt_disable(); 44 if (!n) { 45 seq_printf(m, "vendor_id : IBM/S390\n" 46 "# processors : %i\n" 47 "bogomips per cpu: %lu.%02lu\n", 48 num_online_cpus(), loops_per_jiffy/(500000/HZ), 49 (loops_per_jiffy/(5000/HZ))%100); 50 seq_puts(m, "features\t: "); 51 for (i = 0; i < 10; i++) 52 if (hwcap_str[i] && (elf_hwcap & (1UL << i))) 53 seq_printf(m, "%s ", hwcap_str[i]); 54 seq_puts(m, "\n"); 55 } 56 57 if (cpu_online(n)) { 58 #ifdef CONFIG_SMP 59 lc = (smp_processor_id() == n) ? 60 &S390_lowcore : lowcore_ptr[n]; 61 #else 62 lc = &S390_lowcore; 63 #endif 64 seq_printf(m, "processor %li: " 65 "version = %02X, " 66 "identification = %06X, " 67 "machine = %04X\n", 68 n, lc->cpu_id.version, 69 lc->cpu_id.ident, 70 lc->cpu_id.machine); 71 } 72 preempt_enable(); 73 return 0; 74 } 75 76 static void *c_start(struct seq_file *m, loff_t *pos) 77 { 78 return *pos < NR_CPUS ? (void *)((unsigned long) *pos + 1) : NULL; 79 } 80 81 static void *c_next(struct seq_file *m, void *v, loff_t *pos) 82 { 83 ++*pos; 84 return c_start(m, pos); 85 } 86 87 static void c_stop(struct seq_file *m, void *v) 88 { 89 } 90 91 const struct seq_operations cpuinfo_op = { 92 .start = c_start, 93 .next = c_next, 94 .stop = c_stop, 95 .show = show_cpuinfo, 96 }; 97 98