1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
/*
* S390X specific proc functions for linux-user
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef S390X_TARGET_PROC_H
#define S390X_TARGET_PROC_H
/*
* Emulate what a Linux kernel running in qemu-system-s390x -M accel=tcg would
* show in /proc/cpuinfo.
*
* Skip the following in order to match the missing support in op_ecag():
* - show_cacheinfo().
* - show_cpu_topology().
* - show_cpu_mhz().
*
* Use fixed values for certain fields:
* - bogomips per cpu - from a qemu-system-s390x run.
* - max thread id = 0, since SMT / SIGP_SET_MULTI_THREADING is not supported.
*
* Keep the code structure close to arch/s390/kernel/processor.c.
*/
static void show_facilities(int fd)
{
size_t sizeof_stfl_bytes = 2048;
g_autofree uint8_t *stfl_bytes = g_new0(uint8_t, sizeof_stfl_bytes);
unsigned int bit;
dprintf(fd, "facilities :");
s390_get_feat_block(S390_FEAT_TYPE_STFL, stfl_bytes);
for (bit = 0; bit < sizeof_stfl_bytes * 8; bit++) {
if (test_be_bit(bit, stfl_bytes)) {
dprintf(fd, " %d", bit);
}
}
dprintf(fd, "\n");
}
static int cpu_ident(unsigned long n)
{
return deposit32(0, CPU_ID_BITS - CPU_PHYS_ADDR_BITS, CPU_PHYS_ADDR_BITS,
n);
}
static void show_cpu_summary(CPUArchState *cpu_env, int fd)
{
S390CPUModel *model = env_archcpu(cpu_env)->model;
int num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
uint32_t elf_hwcap = get_elf_hwcap();
const char *hwcap_str;
int i;
dprintf(fd, "vendor_id : IBM/S390\n"
"# processors : %i\n"
"bogomips per cpu: 13370.00\n",
num_cpus);
dprintf(fd, "max thread id : 0\n");
dprintf(fd, "features\t: ");
for (i = 0; i < sizeof(elf_hwcap) * 8; i++) {
if (!(elf_hwcap & (1 << i))) {
continue;
}
hwcap_str = elf_hwcap_str(i);
if (hwcap_str) {
dprintf(fd, "%s ", hwcap_str);
}
}
dprintf(fd, "\n");
show_facilities(fd);
for (i = 0; i < num_cpus; i++) {
dprintf(fd, "processor %d: "
"version = %02X, "
"identification = %06X, "
"machine = %04X\n",
i, model->cpu_ver, cpu_ident(i), model->def->type);
}
}
static void show_cpu_ids(CPUArchState *cpu_env, int fd, unsigned long n)
{
S390CPUModel *model = env_archcpu(cpu_env)->model;
dprintf(fd, "version : %02X\n", model->cpu_ver);
dprintf(fd, "identification : %06X\n", cpu_ident(n));
dprintf(fd, "machine : %04X\n", model->def->type);
}
static void show_cpuinfo(CPUArchState *cpu_env, int fd, unsigned long n)
{
dprintf(fd, "\ncpu number : %ld\n", n);
show_cpu_ids(cpu_env, fd, n);
}
static int open_cpuinfo(CPUArchState *cpu_env, int fd)
{
int num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
int i;
show_cpu_summary(cpu_env, fd);
for (i = 0; i < num_cpus; i++) {
show_cpuinfo(cpu_env, fd, i);
}
return 0;
}
#define HAVE_ARCH_PROC_CPUINFO
#endif /* S390X_TARGET_PROC_H */
|