Add emulation for /proc/cpuinfo for arm architecture. The output below mimics output as seen on debian porterboxes. aarch64 output example: processor : 0 model name : ARMv8 Processor rev 0 (v8l) BogoMIPS : 100.00 Features : swp half thumb fast_mult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae aes pmull sha1 sha2 crc32 CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x1 CPU part : 0xd07 CPU revision : 0 arm 32-bit output example: processor : 0 model name : ARMv7 Processor rev 5 (armv7l) BogoMIPS : 100.00 Features : swp half thumb fast_mult vfp edsp thumbee neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0f CPU part : 0xc07 CPU revision : 5 Signed-off-by: Helge Deller <deller@gmx.de> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20230803214450.647040-3-deller@gmx.de> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
		
			
				
	
	
		
			102 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * 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 */
 |