From: Helge Deller <deller@kernel.org>
To: Stefan Hajnoczi <stefanha@gmail.com>, qemu-devel@nongnu.org
Cc: Helge Deller <deller@gmx.de>,
Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>,
Laurent Vivier <laurent@vivier.eu>,
Max Filippov <jcmvbkbc@gmail.com>,
Richard Henderson <richard.henderson@linaro.org>
Subject: [PULL 2/4] linux-user: Implement /proc/cpuinfo for ppc cpus
Date: Fri, 12 Jun 2026 17:50:41 +0200 [thread overview]
Message-ID: <20260612155043.3552-3-deller@kernel.org> (raw)
In-Reply-To: <20260612155043.3552-1-deller@kernel.org>
From: Helge Deller <deller@gmx.de>
Mimic the entries for /proc/cpuinfo to what can be seen on two debian
porterboxes (ppc64 and ppc64le), which are running via KVM/QEMU.
The "timebase" value in /proc/cpuinfo is used by glibc on power, but only if
the __kernel_get_tbfreq vdso call isn't implemented. So switch
cpu_ppc_load_tbl() for linux-user to get_clock(), as suggested by Richard, and
report timebase = 1GHz in /proc/cpuinfo, which will make the vdso
implementation simple too.
v4: change timebase to 1GHz and use get_clock()
v3: drop another colon, indenting fixes
v2: drop colon, add clock output, refine pvr calculation
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/ppc/cpu_loop.c | 2 +-
linux-user/ppc/target_proc.h | 91 +++++++++++++++++++++++++++++++++++-
2 files changed, 91 insertions(+), 2 deletions(-)
diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c
index 1f9ee20bd0..7c53e25a93 100644
--- a/linux-user/ppc/cpu_loop.c
+++ b/linux-user/ppc/cpu_loop.c
@@ -26,7 +26,7 @@
static inline uint64_t cpu_ppc_get_tb(CPUPPCState *env)
{
- return cpu_get_host_ticks();
+ return get_clock();
}
uint64_t cpu_ppc_load_tbl(CPUPPCState *env)
diff --git a/linux-user/ppc/target_proc.h b/linux-user/ppc/target_proc.h
index 43fe29ca72..0a48fd65e9 100644
--- a/linux-user/ppc/target_proc.h
+++ b/linux-user/ppc/target_proc.h
@@ -1 +1,90 @@
-/* No target-specific /proc support */
+/*
+ * ppc specific proc functions for linux-user
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef PPC_TARGET_PROC_H
+#define PPC_TARGET_PROC_H
+
+#include <time.h>
+
+#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */
+#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */
+#define PVR_MAJ(pvr) (((pvr) >> 4) & 0xF) /* Major revision field */
+#define PVR_MIN(pvr) (((pvr) >> 0) & 0xF) /* Minor revision field */
+
+static int open_cpuinfo(CPUArchState *cpu_env, int fd)
+{
+ struct timespec res;
+ double freq_mhz;
+ int i, num_cpus;
+ unsigned int maj, min, pvr;
+
+ PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(env_cpu(cpu_env));
+ DeviceClass *dc = DEVICE_CLASS(ppc_cpu_get_family_class(pcc));
+
+ pvr = pcc->pvr;
+
+ /* Taken from Linux kernel: */
+ /* If we are a Freescale core do a simple check so
+ * we don't have to keep adding cases in the future */
+ if (PVR_VER(pvr) & 0x8000) {
+ switch (PVR_VER(pvr)) {
+ case 0x8000: /* 7441/7450/7451, Voyager */
+ case 0x8001: /* 7445/7455, Apollo 6 */
+ case 0x8002: /* 7447/7457, Apollo 7 */
+ case 0x8003: /* 7447A, Apollo 7 PM */
+ case 0x8004: /* 7448, Apollo 8 */
+ case 0x800c: /* 7410, Nitro */
+ maj = ((pvr >> 8) & 0xF);
+ min = PVR_MIN(pvr);
+ break;
+ default: /* e500/book-e */
+ maj = PVR_MAJ(pvr);
+ min = PVR_MIN(pvr);
+ break;
+ }
+ } else {
+ switch (PVR_VER(pvr)) {
+ case 0x1008: /* 740P/750P ?? */
+ maj = ((pvr >> 8) & 0xFF) - 1;
+ min = pvr & 0xFF;
+ break;
+ case 0x004e: /* POWER9 bits 12-15 give chip type */
+ case 0x0080: /* POWER10 bit 12 gives SMT8/4 */
+ maj = (pvr >> 8) & 0x0F;
+ min = pvr & 0xFF;
+ break;
+ default:
+ maj = (pvr >> 8) & 0xFF;
+ min = pvr & 0xFF;
+ break;
+ }
+ }
+
+ if (clock_getres(CLOCK_REALTIME, &res) == -1) {
+ res.tv_nsec = 1;
+ }
+ freq_mhz = 1000.0 / res.tv_nsec;
+
+ num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+ for (i = 0; i < num_cpus; i++) {
+ dprintf(fd, "processor\t: %d\n", i);
+ dprintf(fd, "cpu\t\t: %s%s\n",
+ dc->desc,
+ pcc->insns_flags & PPC_ALTIVEC ? ", altivec supported":"");
+ dprintf(fd, "clock\t\t: %.3fMHz\n", freq_mhz);
+ dprintf(fd, "revision\t: %d.%d (pvr %04x %04x)\n\n",
+ maj, min, PVR_VER(pvr), PVR_REV(pvr));
+ }
+
+ dprintf(fd, "timebase\t: 1000000000\n");
+ dprintf(fd, "platform\t: pSeries\n");
+ dprintf(fd, "model\t\t: IBM pSeries (QEMU user v" QEMU_VERSION ")\n");
+ dprintf(fd, "machine\t\t: CHRP IBM pSeries\n");
+
+ return 0;
+}
+#define HAVE_ARCH_PROC_CPUINFO
+
+#endif /* PPC_TARGET_PROC_H */
--
2.54.0
next prev parent reply other threads:[~2026-06-12 15:51 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-12 15:50 [PULL 0/4] Linux user patches Helge Deller
2026-06-12 15:50 ` [PULL 1/4] linux-user: add preadv2/preadv2 Helge Deller
2026-06-12 15:50 ` Helge Deller [this message]
2026-06-12 15:50 ` [PULL 3/4] target/xtensa: add cpu_set_fcr/fsr helpers to sync fp_status Helge Deller
2026-06-12 15:50 ` [PULL 4/4] linux-user/xtensa: save/restore FP registers across signal delivery Helge Deller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260612155043.3552-3-deller@kernel.org \
--to=deller@kernel.org \
--cc=deller@gmx.de \
--cc=jcmvbkbc@gmail.com \
--cc=laurent@vivier.eu \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=stefanha@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.