|  | /* | 
|  | * Arm specific proc functions for linux-user | 
|  | * | 
|  | * SPDX-License-Identifier: GPL-2.0-or-later | 
|  | */ | 
|  | #ifndef ARM_TARGET_PROC_H | 
|  | #define ARM_TARGET_PROC_H | 
|  |  | 
|  | static int open_cpuinfo(CPUArchState *cpu_env, int fd) | 
|  | { | 
|  | ARMCPU *cpu = env_archcpu(cpu_env); | 
|  | int arch, midr_rev, midr_part, midr_var, midr_impl; | 
|  | target_ulong elf_hwcap = get_elf_hwcap(); | 
|  | target_ulong elf_hwcap2 = get_elf_hwcap2(); | 
|  | const char *elf_name; | 
|  | int num_cpus, len_part, len_var; | 
|  |  | 
|  | #if TARGET_BIG_ENDIAN | 
|  | # define END_SUFFIX "b" | 
|  | #else | 
|  | # define END_SUFFIX "l" | 
|  | #endif | 
|  |  | 
|  | arch = 8; | 
|  | elf_name = "v8" END_SUFFIX; | 
|  | midr_rev = FIELD_EX32(cpu->midr, MIDR_EL1, REVISION); | 
|  | midr_part = FIELD_EX32(cpu->midr, MIDR_EL1, PARTNUM); | 
|  | midr_var = FIELD_EX32(cpu->midr, MIDR_EL1, VARIANT); | 
|  | midr_impl = FIELD_EX32(cpu->midr, MIDR_EL1, IMPLEMENTER); | 
|  | len_part = 3; | 
|  | len_var = 1; | 
|  |  | 
|  | #ifndef TARGET_AARCH64 | 
|  | /* For simplicity, treat ARMv8 as an arm64 kernel with CONFIG_COMPAT. */ | 
|  | if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { | 
|  | if (arm_feature(&cpu->env, ARM_FEATURE_V7)) { | 
|  | arch = 7; | 
|  | midr_var = (cpu->midr >> 16) & 0x7f; | 
|  | len_var = 2; | 
|  | if (arm_feature(&cpu->env, ARM_FEATURE_M)) { | 
|  | elf_name = "armv7m" END_SUFFIX; | 
|  | } else { | 
|  | elf_name = "armv7" END_SUFFIX; | 
|  | } | 
|  | } else { | 
|  | midr_part = cpu->midr >> 4; | 
|  | len_part = 7; | 
|  | if (arm_feature(&cpu->env, ARM_FEATURE_V6)) { | 
|  | arch = 6; | 
|  | elf_name = "armv6" END_SUFFIX; | 
|  | } else if (arm_feature(&cpu->env, ARM_FEATURE_V5)) { | 
|  | arch = 5; | 
|  | elf_name = "armv5t" END_SUFFIX; | 
|  | } else { | 
|  | arch = 4; | 
|  | elf_name = "armv4" END_SUFFIX; | 
|  | } | 
|  | } | 
|  | } | 
|  | #endif | 
|  |  | 
|  | #undef END_SUFFIX | 
|  |  | 
|  | num_cpus = sysconf(_SC_NPROCESSORS_ONLN); | 
|  | for (int i = 0; i < num_cpus; i++) { | 
|  | dprintf(fd, | 
|  | "processor\t: %d\n" | 
|  | "model name\t: ARMv%d Processor rev %d (%s)\n" | 
|  | "BogoMIPS\t: 100.00\n" | 
|  | "Features\t:", | 
|  | i, arch, midr_rev, elf_name); | 
|  |  | 
|  | for (target_ulong j = elf_hwcap; j ; j &= j - 1) { | 
|  | dprintf(fd, " %s", elf_hwcap_str(ctz64(j))); | 
|  | } | 
|  | for (target_ulong j = elf_hwcap2; j ; j &= j - 1) { | 
|  | dprintf(fd, " %s", elf_hwcap2_str(ctz64(j))); | 
|  | } | 
|  |  | 
|  | dprintf(fd, "\n" | 
|  | "CPU implementer\t: 0x%02x\n" | 
|  | "CPU architecture: %d\n" | 
|  | "CPU variant\t: 0x%0*x\n", | 
|  | midr_impl, arch, len_var, midr_var); | 
|  | if (arch >= 7) { | 
|  | dprintf(fd, "CPU part\t: 0x%0*x\n", len_part, midr_part); | 
|  | } | 
|  | dprintf(fd, "CPU revision\t: %d\n\n", midr_rev); | 
|  | } | 
|  |  | 
|  | if (arch < 8) { | 
|  | dprintf(fd, "Hardware\t: QEMU v%s %s\n", QEMU_VERSION, | 
|  | cpu->dtb_compatible ? : ""); | 
|  | dprintf(fd, "Revision\t: 0000\n"); | 
|  | dprintf(fd, "Serial\t\t: 0000000000000000\n"); | 
|  | } | 
|  | return 0; | 
|  | } | 
|  | #define HAVE_ARCH_PROC_CPUINFO | 
|  |  | 
|  | #endif /* ARM_TARGET_PROC_H */ |