diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-06-17 20:58:21 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-06-17 20:58:21 +0000 |
commit | 6bef9ad611b3efdb02c0d5ea4bdb20b01ccb6a5f (patch) | |
tree | d010cfef068b2c7a16c6b21a49dce315ad9a5056 | |
parent | 449ba622eccf59a1903d1940704960d3db241272 (diff) |
Print CPU name and cache info in the same way as we do on arm64.
-rw-r--r-- | sys/arch/powerpc64/include/cpufunc.h | 10 | ||||
-rw-r--r-- | sys/arch/powerpc64/powerpc64/cpu.c | 92 |
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. */ |