]>
Commit | Line | Data |
---|---|---|
395d31d4 | 1 | /* |
395d31d4 MS |
2 | * Copyright IBM Corp. 2008 |
3 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | |
4 | */ | |
5 | ||
6 | #define KMSG_COMPONENT "cpu" | |
7 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | |
8 | ||
ca21872e | 9 | #include <linux/cpufeature.h> |
395d31d4 MS |
10 | #include <linux/kernel.h> |
11 | #include <linux/init.h> | |
395d31d4 MS |
12 | #include <linux/seq_file.h> |
13 | #include <linux/delay.h> | |
19726cec | 14 | #include <linux/cpu.h> |
1ec2772e | 15 | #include <asm/diag.h> |
395d31d4 MS |
16 | #include <asm/elf.h> |
17 | #include <asm/lowcore.h> | |
18 | #include <asm/param.h> | |
4d92f502 | 19 | #include <asm/smp.h> |
395d31d4 | 20 | |
94038a99 MS |
21 | static DEFINE_PER_CPU(struct cpuid, cpu_id); |
22 | ||
a9ca8eb7 | 23 | void notrace cpu_relax(void) |
4d92f502 | 24 | { |
1ec2772e MS |
25 | if (!smp_cpu_mtid && MACHINE_HAS_DIAG44) { |
26 | diag_stat_inc(DIAG_STAT_X044); | |
4d92f502 | 27 | asm volatile("diag 0,0,0x44"); |
1ec2772e | 28 | } |
4d92f502 HC |
29 | barrier(); |
30 | } | |
31 | EXPORT_SYMBOL(cpu_relax); | |
32 | ||
94038a99 MS |
33 | /* |
34 | * cpu_init - initializes state that is per-CPU. | |
35 | */ | |
e2741f17 | 36 | void cpu_init(void) |
94038a99 | 37 | { |
eb7e7d76 | 38 | struct cpuid *id = this_cpu_ptr(&cpu_id); |
94038a99 MS |
39 | |
40 | get_cpu_id(id); | |
41 | atomic_inc(&init_mm.mm_count); | |
42 | current->active_mm = &init_mm; | |
43 | BUG_ON(current->mm); | |
44 | enter_lazy_tlb(&init_mm, current); | |
45 | } | |
46 | ||
8f00b3e2 HB |
47 | /* |
48 | * cpu_have_feature - Test CPU features on module initialization | |
49 | */ | |
50 | int cpu_have_feature(unsigned int num) | |
51 | { | |
52 | return elf_hwcap & (1UL << num); | |
53 | } | |
54 | EXPORT_SYMBOL(cpu_have_feature); | |
55 | ||
395d31d4 MS |
56 | /* |
57 | * show_cpuinfo - Get information on one CPU for use by procfs. | |
58 | */ | |
395d31d4 MS |
59 | static int show_cpuinfo(struct seq_file *m, void *v) |
60 | { | |
fbf3c542 | 61 | static const char *hwcap_str[] = { |
395d31d4 | 62 | "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", |
80703617 | 63 | "edat", "etf3eh", "highgprs", "te", "vx" |
395d31d4 | 64 | }; |
7f16d7e7 DH |
65 | static const char * const int_hwcap_str[] = { |
66 | "sie" | |
67 | }; | |
7b468488 MS |
68 | unsigned long n = (unsigned long) v - 1; |
69 | int i; | |
395d31d4 | 70 | |
7b468488 | 71 | if (!n) { |
8e102301 | 72 | s390_adjust_jiffies(); |
7b468488 MS |
73 | seq_printf(m, "vendor_id : IBM/S390\n" |
74 | "# processors : %i\n" | |
75 | "bogomips per cpu: %lu.%02lu\n", | |
76 | num_online_cpus(), loops_per_jiffy/(500000/HZ), | |
77 | (loops_per_jiffy/(5000/HZ))%100); | |
78 | seq_puts(m, "features\t: "); | |
fbf3c542 | 79 | for (i = 0; i < ARRAY_SIZE(hwcap_str); i++) |
7b468488 MS |
80 | if (hwcap_str[i] && (elf_hwcap & (1UL << i))) |
81 | seq_printf(m, "%s ", hwcap_str[i]); | |
7f16d7e7 DH |
82 | for (i = 0; i < ARRAY_SIZE(int_hwcap_str); i++) |
83 | if (int_hwcap_str[i] && (int_hwcap & (1UL << i))) | |
84 | seq_printf(m, "%s ", int_hwcap_str[i]); | |
7b468488 | 85 | seq_puts(m, "\n"); |
6668022c | 86 | show_cacheinfo(m); |
7b468488 | 87 | } |
7b468488 | 88 | if (cpu_online(n)) { |
94038a99 | 89 | struct cpuid *id = &per_cpu(cpu_id, n); |
7b468488 MS |
90 | seq_printf(m, "processor %li: " |
91 | "version = %02X, " | |
92 | "identification = %06X, " | |
93 | "machine = %04X\n", | |
94038a99 | 94 | n, id->version, id->ident, id->machine); |
7b468488 | 95 | } |
7b468488 | 96 | return 0; |
395d31d4 MS |
97 | } |
98 | ||
281eaa8c HC |
99 | static inline void *c_update(loff_t *pos) |
100 | { | |
101 | if (*pos) | |
102 | *pos = cpumask_next(*pos - 1, cpu_online_mask); | |
103 | return *pos < nr_cpu_ids ? (void *)*pos + 1 : NULL; | |
104 | } | |
105 | ||
395d31d4 MS |
106 | static void *c_start(struct seq_file *m, loff_t *pos) |
107 | { | |
281eaa8c HC |
108 | get_online_cpus(); |
109 | return c_update(pos); | |
395d31d4 MS |
110 | } |
111 | ||
112 | static void *c_next(struct seq_file *m, void *v, loff_t *pos) | |
113 | { | |
114 | ++*pos; | |
281eaa8c | 115 | return c_update(pos); |
395d31d4 MS |
116 | } |
117 | ||
118 | static void c_stop(struct seq_file *m, void *v) | |
119 | { | |
281eaa8c | 120 | put_online_cpus(); |
395d31d4 MS |
121 | } |
122 | ||
123 | const struct seq_operations cpuinfo_op = { | |
124 | .start = c_start, | |
125 | .next = c_next, | |
126 | .stop = c_stop, | |
127 | .show = show_cpuinfo, | |
128 | }; | |
129 |