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