summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-06-17 20:58:21 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-06-17 20:58:21 +0000
commit6bef9ad611b3efdb02c0d5ea4bdb20b01ccb6a5f (patch)
treed010cfef068b2c7a16c6b21a49dce315ad9a5056
parent449ba622eccf59a1903d1940704960d3db241272 (diff)
Print CPU name and cache info in the same way as we do on arm64.
-rw-r--r--sys/arch/powerpc64/include/cpufunc.h10
-rw-r--r--sys/arch/powerpc64/powerpc64/cpu.c92
2 files changed, 95 insertions, 7 deletions
diff --git a/sys/arch/powerpc64/include/cpufunc.h b/sys/arch/powerpc64/include/cpufunc.h
index 4803107d7dd..c5ee968750f 100644
--- a/sys/arch/powerpc64/include/cpufunc.h
+++ b/sys/arch/powerpc64/include/cpufunc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpufunc.h,v 1.4 2020/06/09 18:58:14 kettenis Exp $ */
+/* $OpenBSD: cpufunc.h,v 1.5 2020/06/17 20:58:20 kettenis Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
@@ -125,6 +125,14 @@ mtdec(uint32_t value)
__asm volatile ("mtdec %0" :: "r"(value));
}
+static inline uint32_t
+mfpvr(void)
+{
+ uint32_t value;
+ __asm volatile ("mfspr %0, 287" : "=r"(value));
+ return value;
+}
+
static inline uint64_t
mflpcr(void)
{
diff --git a/sys/arch/powerpc64/powerpc64/cpu.c b/sys/arch/powerpc64/powerpc64/cpu.c
index 26bdf0c0c7c..8483c9965c4 100644
--- a/sys/arch/powerpc64/powerpc64/cpu.c
+++ b/sys/arch/powerpc64/powerpc64/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.6 2020/06/10 19:06:53 kettenis Exp $ */
+/* $OpenBSD: cpu.c,v 1.7 2020/06/17 20:58:20 kettenis Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
@@ -27,6 +27,29 @@
#include <dev/ofw/openfirm.h>
#include <dev/ofw/fdt.h>
+/* CPU Identification. */
+#define CPU_IBMPOWER8E 0x004b
+#define CPU_IBMPOWER8NVL 0x004c
+#define CPU_IBMPOWER8 0x004d
+#define CPU_IBMPOWER9 0x004e
+
+#define CPU_VERSION(pvr) ((pvr) >> 16)
+#define CPU_REV_MAJ(pvr) (((pvr) >> 8) & 0xf)
+#define CPU_REV_MIN(pvr) (((pvr) >> 0) & 0xf)
+
+struct cpu_version {
+ int version;
+ const char *name;
+};
+
+struct cpu_version cpu_version[] = {
+ { CPU_IBMPOWER8, "IBM POWER8" },
+ { CPU_IBMPOWER8E, "IBM POWER8E" },
+ { CPU_IBMPOWER8NVL, "IBM POWER8NVL" },
+ { CPU_IBMPOWER9, "IBM POWER9" },
+ { 0, NULL }
+};
+
char cpu_model[64];
uint64_t tb_freq = 512000000; /* POWER8, POWER9 */
@@ -63,15 +86,72 @@ void
cpu_attach(struct device *parent, struct device *dev, void *aux)
{
struct fdt_attach_args *faa = aux;
- char name[64];
+ const char *name;
+ uint32_t pvr;
+ uint32_t iline;
+ uint32_t dline;
+ int node, level, i;
- printf(" pir %llx:", faa->fa_reg[0].addr);
+ printf(" pir %llx", faa->fa_reg[0].addr);
- if (OF_getprop(faa->fa_node, "name", &name, sizeof(name)) > 0) {
- name[sizeof(name) - 1] = 0;
- printf(" %s", name);
+ pvr = mfpvr();
+
+ for (i = 0; cpu_version[i].name; i++) {
+ if (CPU_VERSION(pvr) == cpu_version[i].version) {
+ name = cpu_version[i].name;
+ break;
+ }
+ }
+
+ if (name) {
+ printf(": %s %d.%d", name, CPU_REV_MAJ(pvr), CPU_REV_MIN(pvr));
+ snprintf(cpu_model, sizeof(cpu_model), "%s %d.%d",
+ name, CPU_REV_MAJ(pvr), CPU_REV_MIN(pvr));
+ } else {
+ printf(": Unknown, PVR 0x%x", pvr);
+ strlcpy(cpu_model, "Unknown", sizeof(cpu_model));
}
+
+ node = faa->fa_node;
+ iline = OF_getpropint(node, "i-cache-block-size", 128);
+ dline = OF_getpropint(node, "d-cache-block-size", 128);
+ level = 1;
+
+ while (node) {
+ const char *unit = "KB";
+ uint32_t isize, iways;
+ uint32_t dsize, dways;
+ uint32_t cache;
+
+ isize = OF_getpropint(node, "i-cache-size", 0) / 1024;
+ iways = OF_getpropint(node, "i-cache-sets", 0);
+ dsize = OF_getpropint(node, "d-cache-size", 0) / 1024;
+ dways = OF_getpropint(node, "d-cache-sets", 0);
+
+ /* Print large cache sizes in MB. */
+ if (isize > 4096 && dsize > 4096) {
+ unit = "MB";
+ isize /= 1024;
+ dsize /= 1024;
+ }
+
+ printf("\n%s:", dev->dv_xname);
+ if (OF_getproplen(node, "cache-unified") == 0) {
+ printf(" %d%s %db/line %d-way L%d cache",
+ isize, unit, iline, iways, level);
+ } else {
+ printf(" %d%s %db/line %d-way L%d I-cache",
+ isize, unit, iline, iways, level);
+ printf(", %d%s %db/line %d-way L%d D-cache",
+ dsize, unit, dline, dways, level);
+ }
+
+ cache = OF_getpropint(node, "l2-cache", 0);
+ node = OF_getnodebyphandle(cache);
+ level++;
+ }
+
printf("\n");
/* Update timebase frequency to reflect reality. */