1395d31d4SMartin Schwidefsky /* 2395d31d4SMartin Schwidefsky * arch/s390/kernel/processor.c 3395d31d4SMartin Schwidefsky * 4395d31d4SMartin Schwidefsky * Copyright IBM Corp. 2008 5395d31d4SMartin Schwidefsky * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 6395d31d4SMartin Schwidefsky */ 7395d31d4SMartin Schwidefsky 8395d31d4SMartin Schwidefsky #define KMSG_COMPONENT "cpu" 9395d31d4SMartin Schwidefsky #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10395d31d4SMartin Schwidefsky 11395d31d4SMartin Schwidefsky #include <linux/kernel.h> 12395d31d4SMartin Schwidefsky #include <linux/init.h> 13395d31d4SMartin Schwidefsky #include <linux/smp.h> 14395d31d4SMartin Schwidefsky #include <linux/seq_file.h> 15395d31d4SMartin Schwidefsky #include <linux/delay.h> 16395d31d4SMartin Schwidefsky 17395d31d4SMartin Schwidefsky #include <asm/elf.h> 18395d31d4SMartin Schwidefsky #include <asm/lowcore.h> 19395d31d4SMartin Schwidefsky #include <asm/param.h> 20395d31d4SMartin Schwidefsky 217b468488SMartin Schwidefsky void __cpuinit print_cpu_info(void) 22395d31d4SMartin Schwidefsky { 23395d31d4SMartin Schwidefsky pr_info("Processor %d started, address %d, identification %06X\n", 247b468488SMartin Schwidefsky S390_lowcore.cpu_nr, S390_lowcore.cpu_addr, 257b468488SMartin Schwidefsky S390_lowcore.cpu_id.ident); 26395d31d4SMartin Schwidefsky } 27395d31d4SMartin Schwidefsky 28395d31d4SMartin Schwidefsky /* 29395d31d4SMartin Schwidefsky * show_cpuinfo - Get information on one CPU for use by procfs. 30395d31d4SMartin Schwidefsky */ 31395d31d4SMartin Schwidefsky 32395d31d4SMartin Schwidefsky static int show_cpuinfo(struct seq_file *m, void *v) 33395d31d4SMartin Schwidefsky { 34be6e3f9cSAndreas Krebbel static const char *hwcap_str[10] = { 35395d31d4SMartin Schwidefsky "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", 36be6e3f9cSAndreas Krebbel "edat", "etf3eh", "highgprs" 37395d31d4SMartin Schwidefsky }; 387b468488SMartin Schwidefsky struct _lowcore *lc; 39395d31d4SMartin Schwidefsky unsigned long n = (unsigned long) v - 1; 40395d31d4SMartin Schwidefsky int i; 41395d31d4SMartin Schwidefsky 42395d31d4SMartin Schwidefsky s390_adjust_jiffies(); 43395d31d4SMartin Schwidefsky preempt_disable(); 44395d31d4SMartin Schwidefsky if (!n) { 45395d31d4SMartin Schwidefsky seq_printf(m, "vendor_id : IBM/S390\n" 46395d31d4SMartin Schwidefsky "# processors : %i\n" 47395d31d4SMartin Schwidefsky "bogomips per cpu: %lu.%02lu\n", 48395d31d4SMartin Schwidefsky num_online_cpus(), loops_per_jiffy/(500000/HZ), 49395d31d4SMartin Schwidefsky (loops_per_jiffy/(5000/HZ))%100); 50395d31d4SMartin Schwidefsky seq_puts(m, "features\t: "); 51be6e3f9cSAndreas Krebbel for (i = 0; i < 10; i++) 52395d31d4SMartin Schwidefsky if (hwcap_str[i] && (elf_hwcap & (1UL << i))) 53395d31d4SMartin Schwidefsky seq_printf(m, "%s ", hwcap_str[i]); 54395d31d4SMartin Schwidefsky seq_puts(m, "\n"); 55395d31d4SMartin Schwidefsky } 56395d31d4SMartin Schwidefsky 57395d31d4SMartin Schwidefsky if (cpu_online(n)) { 58395d31d4SMartin Schwidefsky #ifdef CONFIG_SMP 597b468488SMartin Schwidefsky lc = (smp_processor_id() == n) ? 607b468488SMartin Schwidefsky &S390_lowcore : lowcore_ptr[n]; 61395d31d4SMartin Schwidefsky #else 627b468488SMartin Schwidefsky lc = &S390_lowcore; 63395d31d4SMartin Schwidefsky #endif 64395d31d4SMartin Schwidefsky seq_printf(m, "processor %li: " 65395d31d4SMartin Schwidefsky "version = %02X, " 66395d31d4SMartin Schwidefsky "identification = %06X, " 67395d31d4SMartin Schwidefsky "machine = %04X\n", 687b468488SMartin Schwidefsky n, lc->cpu_id.version, 697b468488SMartin Schwidefsky lc->cpu_id.ident, 707b468488SMartin Schwidefsky lc->cpu_id.machine); 71395d31d4SMartin Schwidefsky } 72395d31d4SMartin Schwidefsky preempt_enable(); 73395d31d4SMartin Schwidefsky return 0; 74395d31d4SMartin Schwidefsky } 75395d31d4SMartin Schwidefsky 76395d31d4SMartin Schwidefsky static void *c_start(struct seq_file *m, loff_t *pos) 77395d31d4SMartin Schwidefsky { 78395d31d4SMartin Schwidefsky return *pos < NR_CPUS ? (void *)((unsigned long) *pos + 1) : NULL; 79395d31d4SMartin Schwidefsky } 80395d31d4SMartin Schwidefsky 81395d31d4SMartin Schwidefsky static void *c_next(struct seq_file *m, void *v, loff_t *pos) 82395d31d4SMartin Schwidefsky { 83395d31d4SMartin Schwidefsky ++*pos; 84395d31d4SMartin Schwidefsky return c_start(m, pos); 85395d31d4SMartin Schwidefsky } 86395d31d4SMartin Schwidefsky 87395d31d4SMartin Schwidefsky static void c_stop(struct seq_file *m, void *v) 88395d31d4SMartin Schwidefsky { 89395d31d4SMartin Schwidefsky } 90395d31d4SMartin Schwidefsky 91395d31d4SMartin Schwidefsky const struct seq_operations cpuinfo_op = { 92395d31d4SMartin Schwidefsky .start = c_start, 93395d31d4SMartin Schwidefsky .next = c_next, 94395d31d4SMartin Schwidefsky .stop = c_stop, 95395d31d4SMartin Schwidefsky .show = show_cpuinfo, 96395d31d4SMartin Schwidefsky }; 97395d31d4SMartin Schwidefsky 98