Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
linux-user: Emulate /proc/cpuinfo output for riscv
RISC-V does not expose all extensions via hwcaps, thus some userspace
applications may want to query these via /proc/cpuinfo.

Currently when querying this file the host's file is shown instead
which is slightly confusing. Emulate a basic /proc/cpuinfo file
with mmu info and an ISA string.

Signed-off-by: Afonso Bordado <afonsobordado@gmail.com>
Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com>
Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Message-Id: <167873059442.9885.15152085316575248452-0@git.sr.ht>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
  • Loading branch information
afonso360 authored and vivier committed May 16, 2023
1 parent 7c18f2d commit de52cbd
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
34 changes: 32 additions & 2 deletions linux-user/syscall.c
Expand Up @@ -8231,7 +8231,8 @@ void target_exception_dump(CPUArchState *env, const char *fmt, int code)
}

#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN || \
defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA)
defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA) || \
defined(TARGET_RISCV)
static int is_proc(const char *filename, const char *entry)
{
return strcmp(filename, entry) == 0;
Expand Down Expand Up @@ -8309,6 +8310,35 @@ static int open_cpuinfo(CPUArchState *cpu_env, int fd)
}
#endif

#if defined(TARGET_RISCV)
static int open_cpuinfo(CPUArchState *cpu_env, int fd)
{
int i;
int num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
RISCVCPU *cpu = env_archcpu(cpu_env);
const RISCVCPUConfig *cfg = riscv_cpu_cfg((CPURISCVState *) cpu_env);
char *isa_string = riscv_isa_string(cpu);
const char *mmu;

if (cfg->mmu) {
mmu = (cpu_env->xl == MXL_RV32) ? "sv32" : "sv48";
} else {
mmu = "none";
}

for (i = 0; i < num_cpus; i++) {
dprintf(fd, "processor\t: %d\n", i);
dprintf(fd, "hart\t\t: %d\n", i);
dprintf(fd, "isa\t\t: %s\n", isa_string);
dprintf(fd, "mmu\t\t: %s\n", mmu);
dprintf(fd, "uarch\t\t: qemu\n\n");
}

g_free(isa_string);
return 0;
}
#endif

#if defined(TARGET_M68K)
static int open_hardware(CPUArchState *cpu_env, int fd)
{
Expand All @@ -8333,7 +8363,7 @@ static int do_openat(CPUArchState *cpu_env, int dirfd, const char *pathname, int
#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN
{ "/proc/net/route", open_net_route, is_proc },
#endif
#if defined(TARGET_SPARC) || defined(TARGET_HPPA)
#if defined(TARGET_SPARC) || defined(TARGET_HPPA) || defined(TARGET_RISCV)
{ "/proc/cpuinfo", open_cpuinfo, is_proc },
#endif
#if defined(TARGET_M68K)
Expand Down
1 change: 1 addition & 0 deletions tests/tcg/riscv64/Makefile.target
Expand Up @@ -4,6 +4,7 @@
VPATH += $(SRC_PATH)/tests/tcg/riscv64
TESTS += test-div
TESTS += noexec
TESTS += cpuinfo

# Disable compressed instructions for test-noc
TESTS += test-noc
Expand Down
31 changes: 31 additions & 0 deletions tests/tcg/riscv64/cpuinfo.c
@@ -0,0 +1,31 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define BUFFER_SIZE 1024

int main(void)
{
char buffer[BUFFER_SIZE];
FILE *fp = fopen("/proc/cpuinfo", "r");
assert(fp != NULL);

while (fgets(buffer, BUFFER_SIZE, fp) != NULL) {
if (strstr(buffer, "processor") != NULL) {
assert(strstr(buffer, "processor\t: ") == buffer);
} else if (strstr(buffer, "hart") != NULL) {
assert(strstr(buffer, "hart\t\t: ") == buffer);
} else if (strstr(buffer, "isa") != NULL) {
assert(strcmp(buffer, "isa\t\t: rv64imafdc_zicsr_zifencei\n") == 0);
} else if (strstr(buffer, "mmu") != NULL) {
assert(strcmp(buffer, "mmu\t\t: sv48\n") == 0);
} else if (strstr(buffer, "uarch") != NULL) {
assert(strcmp(buffer, "uarch\t\t: qemu\n") == 0);
break;
}
}

fclose(fp);
return 0;
}

0 comments on commit de52cbd

Please sign in to comment.