Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 8 Jul 2016 01:32:43 +0000 (UTC)
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r302416 - projects/powernv/powerpc/powernv
Message-ID:  <201607080132.u681WhgC029630@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: nwhitehorn
Date: Fri Jul  8 01:32:43 2016
New Revision: 302416
URL: https://svnweb.freebsd.org/changeset/base/302416

Log:
  Get system booting to the point that PCI bus enumeration fails.

Modified:
  projects/powernv/powerpc/powernv/platform_powernv.c

Modified: projects/powernv/powerpc/powernv/platform_powernv.c
==============================================================================
--- projects/powernv/powerpc/powernv/platform_powernv.c	Fri Jul  8 01:31:28 2016	(r302415)
+++ projects/powernv/powerpc/powernv/platform_powernv.c	Fri Jul  8 01:32:43 2016	(r302416)
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/ofw/openfirm.h>
 #include <machine/ofw_machdep.h>
+#include <powerpc/aim/mmu_oea64.h>
 
 #include "platform_if.h"
 #include "opal.h"
@@ -113,17 +114,97 @@ powernv_probe(platform_t plat)
 static int
 powernv_attach(platform_t plat)
 {
+	uint32_t nptlp, shift = 0, slb_encoding = 0;
+	int32_t lp_size, lp_encoding;
+	char buf[255];
+	pcell_t prop;
+	phandle_t cpu;
+	int res, len, node, idx;
+
 	/* Ping OPAL again just to make sure */
 	opal_check();
 
 	cpu_idle_hook = powernv_cpu_idle;
 
 	/* Direct interrupts to SRR instead of HSRR */
-	mtspr(SPR_LPCR, mfspr(SPR_LPCR) | LPCR_LPES);
+	mtspr(SPR_LPCR, LPCR_LPES);
 
+	/* Set SLB count from device tree */
+	cpu = OF_peer(0);
+	cpu = OF_child(cpu);
+	while (cpu != 0) {
+		res = OF_getprop(cpu, "name", buf, sizeof(buf));
+		if (res > 0 && strcmp(buf, "cpus") == 0)
+			break;
+		cpu = OF_peer(cpu);
+	}
+	if (cpu == 0)
+		goto out;
+
+	cpu = OF_child(cpu);
+	while (cpu != 0) {
+		res = OF_getprop(cpu, "device_type", buf, sizeof(buf));
+		if (res > 0 && strcmp(buf, "cpu") == 0)
+			break;
+		cpu = OF_peer(cpu);
+	}
+	if (cpu == 0)
+		goto out;
+
+	res = OF_getencprop(cpu, "ibm,slb-size", &prop, sizeof(prop));
+	if (res > 0)
+		n_slbs = prop;
+
+	/*
+	 * Scan the large page size property for PAPR compatible machines.
+	 * See PAPR D.5 Changes to Section 5.1.4, 'CPU Node Properties'
+	 * for the encoding of the property.
+	 */
+
+	len = OF_getproplen(node, "ibm,segment-page-sizes");
+	if (len > 0) {
+		/*
+		 * We have to use a variable length array on the stack
+		 * since we have very limited stack space.
+		 */
+		pcell_t arr[len/sizeof(cell_t)];
+		res = OF_getencprop(cpu, "ibm,segment-page-sizes", arr,
+		    sizeof(arr));
+		len /= 4;
+		idx = 0;
+		while (len > 0) {
+			shift = arr[idx];
+			slb_encoding = arr[idx + 1];
+			nptlp = arr[idx + 2];
+			idx += 3;
+			len -= 3;
+			while (len > 0 && nptlp) {
+				lp_size = arr[idx];
+				lp_encoding = arr[idx+1];
+				if (slb_encoding == SLBV_L && lp_encoding == 0)
+					break;
+
+				idx += 2;
+				len -= 2;
+				nptlp--;
+			}
+			if (nptlp && slb_encoding == SLBV_L && lp_encoding == 0)
+				break;
+		}
+
+		if (len == 0)
+			panic("Standard large pages (SLB[L] = 1, PTE[LP] = 0) "
+			    "not supported by this system.");
+
+		moea64_large_page_shift = shift;
+		moea64_large_page_size = 1ULL << lp_size;
+	}
+
+out:
 	return (0);
 }
 
+
 void
 powernv_mem_regions(platform_t plat, struct mem_region *phys, int *physsz,
     struct mem_region *avail, int *availsz)
@@ -256,6 +337,10 @@ powernv_smp_get_bsp(platform_t plat, str
 	if (res < 0)
 		return (ENOENT);
 
+	/* XXX: FDT from kexec lies sometimes. PIR seems not to */
+	if (cpuid == 0)
+		cpuid = mfspr(SPR_PIR);
+
 	cpuref->cr_cpuid = cpuid;
 
 	if (powernv_smp_first_cpu(plat, &i) != 0)
@@ -299,7 +384,7 @@ powernv_smp_topo(platform_t plat)
 
 	ncores = ncpus = 0;
 	last_pc = NULL;
-	for (i = 0; i <= mp_maxid; i++) {
+	CPU_FOREACH(i) {
 		pc = pcpu_find(i);
 		if (pc == NULL)
 			continue;
@@ -319,7 +404,11 @@ powernv_smp_topo(platform_t plat)
 	if (ncpus == ncores)
 		return (smp_topo_none());
 
+#ifdef NOTYET /* smp_topo_1level() fails with non-consecutive CPU IDs */
 	return (smp_topo_1level(CG_SHARE_L1, ncpus / ncores, CG_FLAG_SMT));
+#else
+	return (smp_topo_none());
+#endif
 }
 #endif
 



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