Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Sep 2021 11:35:05 GMT
From:      Leandro Lupori <luporl@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: cc8e726c85be - stable/13 - powerpc64: change CAS to support Radix MMU
Message-ID:  <202109301135.18UBZ5as052514@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by luporl:

URL: https://cgit.FreeBSD.org/src/commit/?id=cc8e726c85bee3f3da0fb02c12028f2310a7ee17

commit cc8e726c85bee3f3da0fb02c12028f2310a7ee17
Author:     Leandro Lupori <luporl@FreeBSD.org>
AuthorDate: 2021-09-15 18:12:37 +0000
Commit:     Leandro Lupori <luporl@FreeBSD.org>
CommitDate: 2021-09-30 11:34:16 +0000

    powerpc64: change CAS to support Radix MMU
    
    Use radix_mmu environment variable to select between Hash or Radix
    MMU, when performing the CAS method call. This matches kernel's
    behavior, by selecting Hash MMU by default and Radix if radix_mmu
    is not zero, to make sure that both loader and kernel always select
    the same MMU.
    
    The device tree is queried to detect Radix/GTSE support and to
    find out if CAS is supported, making the old CPU version and HV
    bit checks unnecessary now.
    
    Reviewed by:            jhibbits
    Sponsored by:           Instituto de Pesquisas Eldorado (eldorado.org.br)
    Differential Revision:  https://reviews.freebsd.org/D31951
    
    (cherry picked from commit a58abcde2c83b71e5bf19575750564f7bff78833)
---
 stand/powerpc/ofw/cas.c | 120 +++++++++++++++++++++++++++++-------------------
 1 file changed, 74 insertions(+), 46 deletions(-)

diff --git a/stand/powerpc/ofw/cas.c b/stand/powerpc/ofw/cas.c
index 96d276386b71..4f36a147f36d 100644
--- a/stand/powerpc/ofw/cas.c
+++ b/stand/powerpc/ofw/cas.c
@@ -29,6 +29,13 @@ __FBSDID("$FreeBSD$");
 #include <openfirm.h>
 #include <stand.h>
 
+/* #define CAS_DEBUG */
+#ifdef CAS_DEBUG
+#define DPRINTF(fmt, ...)	printf(fmt, ## __VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)	do { ; } while (0)
+#endif
+
 /* PVR */
 #define PVR_CPU_P8E		0x004b0000
 #define PVR_CPU_P8NVL		0x004c0000
@@ -83,13 +90,19 @@ __FBSDID("$FreeBSD$");
 #define OV5_INTC_XICS		0
 
 /* byte 24: MMU */
+#define OV5_MMU_INDEX		24
 #define OV5_MMU_HPT		0
+#define OV5_MMU_RADIX		0x40
+#define OV5_MMU_EITHER		0x80
+#define OV5_MMU_DYNAMIC		0xc0
 
 /* byte 25: HPT MMU Extensions */
-#define OV5_HPT_EXT_NONE	0
+#define OV5_HPT_EXT_INDEX	25
+#define OV5_HPT_GTSE		0x40
 
 /* byte 26: Radix MMU Extensions */
-#define OV5_RPT_EXT_NONE	0
+#define OV5_RADIX_EXT_INDEX	26
+#define OV5_RADIX_GTSE		0x40
 
 
 struct pvr {
@@ -163,69 +176,84 @@ static struct ibm_arch_vec {
 		0,	/* DRMEM_V2 */
 		OV5_INTC_XICS,
 		OV5_MMU_HPT,
-		OV5_HPT_EXT_NONE,
-		OV5_RPT_EXT_NONE
+		0,
+		0
 	}
 };
 
-static __inline register_t
-mfpvr(void)
-{
-	register_t value;
-
-	__asm __volatile ("mfpvr %0" : "=r"(value));
-
-	return (value);
-}
-
-static __inline int
-ppc64_hv(void)
-{
-	int hv;
-
-	/* PSL_HV is bit 3 of 64-bit MSR */
-	__asm __volatile ("mfmsr %0\n\t"
-		"rldicl %0,%0,4,63" : "=r"(hv));
-
-	return (hv);
-}
-
 int
 ppc64_cas(void)
 {
-	int rc;
-	ihandle_t ihandle;
+	phandle_t pkg;
+	ihandle_t inst;
 	cell_t err;
+	uint8_t buf[16], idx, val;
+	int i, len, rc, radix_mmu;
+	const char *var;
+	char *ov5;
+
+	pkg = OF_finddevice("/chosen");
+	if (pkg == -1) {
+		printf("cas: couldn't find /chosen\n");
+		return (-1);
+	}
+
+	len = OF_getprop(pkg, "ibm,arch-vec-5-platform-support", buf,
+	    sizeof(buf));
+	if (len == -1)
+		/* CAS not supported */
+		return (0);
 
-	/* Perform CAS only for POWER8 and later cores */
-	switch (mfpvr() & PVR_CPU_MASK) {
-		case PVR_CPU_P8:
-		case PVR_CPU_P8E:
-		case PVR_CPU_P8NVL:
-		case PVR_CPU_P9:
+	radix_mmu = 0;
+	ov5 = ibm_arch_vec.vec5.data;
+	for (i = 0; i < len; i += 2) {
+		idx = buf[i];
+		val = buf[i + 1];
+		DPRINTF("idx 0x%02x val 0x%02x\n", idx, val);
+
+		switch (idx) {
+		case OV5_MMU_INDEX:
+			/*
+			 * Note that testing for OV5_MMU_RADIX/OV5_MMU_EITHER
+			 * also covers OV5_MMU_DYNAMIC.
+			 */
+			if ((val & OV5_MMU_RADIX) || (val & OV5_MMU_EITHER))
+				radix_mmu = 1;
 			break;
+
+		case OV5_RADIX_EXT_INDEX:
+			if (val & OV5_RADIX_GTSE)
+				ov5[idx] = OV5_RADIX_GTSE;
+			break;
+
+		case OV5_HPT_EXT_INDEX:
 		default:
-			return (0);
+			break;
+		}
 	}
 
-	/* Skip CAS when running on PowerNV */
-	if (ppc64_hv())
-		return (0);
+	if (radix_mmu && (var = getenv("radix_mmu")) != NULL && var[0] != '0')
+		ov5[OV5_MMU_INDEX] = OV5_MMU_RADIX;
+	else
+		radix_mmu = 0;
 
-	ihandle = OF_open("/");
-	if (ihandle == -1) {
+	inst = OF_open("/");
+	if (inst == -1) {
 		printf("cas: failed to open / node\n");
 		return (-1);
 	}
 
-	if (rc = OF_call_method("ibm,client-architecture-support",
-	    ihandle, 1, 1, &ibm_arch_vec, &err))
-		printf("cas: failed to call CAS method\n");
-	else if (err) {
-		printf("cas: error: 0x%08lX\n", err);
+	DPRINTF("MMU 0x%02x RADIX_EXT 0x%02x\n",
+	    ov5[OV5_MMU_INDEX], ov5[OV5_RADIX_EXT_INDEX]);
+	rc = OF_call_method("ibm,client-architecture-support",
+	    inst, 1, 1, &ibm_arch_vec, &err);
+	if (rc != 0 || err) {
+		printf("cas: CAS method returned an error: rc %d err %jd\n",
+		    rc, (intmax_t)err);
 		rc = -1;
 	}
 
-	OF_close(ihandle);
+	OF_close(inst);
+	printf("cas: selected %s MMU\n", radix_mmu ? "radix" : "hash");
 	return (rc);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202109301135.18UBZ5as052514>