| /* | 
 |  * 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 */ |