svn commit: r338922 - head/sys/powerpc/ofw

Justin Hibbits jhibbits at FreeBSD.org
Tue Sep 25 02:34:29 UTC 2018


Author: jhibbits
Date: Tue Sep 25 02:34:28 2018
New Revision: 338922
URL: https://svnweb.freebsd.org/changeset/base/338922

Log:
  powerpc: Blacklist the top 64kB range of the lower 4GB PA space
  
  The PHB4 host bridge used by the POWER9 uses a 64kB range in 32-bit
  space at the address 0xffff0000-0xffffffff.  Reserve this range so that
  DMA memory cannot be allocated within this range.  This fixes seemingly
  random crashes on a POWER9 system.  Ideally this range will have been
  reserved by the firmware, but as of now this is not the case.
  
  Submitted by:	git_bdragon.rtk0.net
  Reviewed by:	nwhitehorn
  Approved by:	re(kib)
  Differential Revision:	https://reviews.freebsd.org/D17183

Modified:
  head/sys/powerpc/ofw/ofw_machdep.c

Modified: head/sys/powerpc/ofw/ofw_machdep.c
==============================================================================
--- head/sys/powerpc/ofw/ofw_machdep.c	Mon Sep 24 22:15:04 2018	(r338921)
+++ head/sys/powerpc/ofw/ofw_machdep.c	Tue Sep 25 02:34:28 2018	(r338922)
@@ -69,6 +69,10 @@ __FBSDID("$FreeBSD$");
 
 #include <contrib/libfdt/libfdt.h>
 
+#ifdef POWERNV
+#include <powerpc/powernv/opal.h>
+#endif
+
 static void	*fdt;
 int		ofw_real_mode;
 
@@ -338,7 +342,35 @@ excise_initrd_region(struct mem_region *avail, int asz
 	return (asz);
 }
 
+#ifdef POWERNV
 static int
+excise_msi_region(struct mem_region *avail, int asz)
+{
+        uint64_t start, end;
+        struct mem_region initrdmap[1];
+
+	/*
+	 * This range of physical addresses is used to implement optimized
+	 * 32 bit MSI interrupts on POWER9. Exclude it to avoid accidentally
+	 * using it for DMA, as this will cause an immediate PHB fence.
+	 * While we could theoretically turn off this behavior in the ETU,
+	 * doing so would break 32-bit MSI, so just reserve the range in 
+	 * the physical map instead.
+	 * See section 4.4.2.8 of the PHB4 specification.
+	 */
+	start	= 0x00000000ffff0000ul;
+	end	= 0x00000000fffffffful;
+
+	initrdmap[0].mr_start = start;
+	initrdmap[0].mr_size = end - start;
+
+	asz = excise_reserved_regions(avail, asz, initrdmap, 1);
+
+	return (asz);
+}
+#endif
+
+static int
 excise_fdt_reserved(struct mem_region *avail, int asz)
 {
 	struct mem_region fdtmap[32];
@@ -428,6 +460,11 @@ ofw_mem_regions(struct mem_region *memp, int *memsz,
 	 */
 	if (OF_hasprop(phandle, "linux,initrd-start"))
 		asz = excise_initrd_region(availp, asz);
+#endif
+
+#ifdef POWERNV
+	if (opal_check() == 0)
+		asz = excise_msi_region(availp, asz);
 #endif
 
 	*memsz = msz;


More information about the svn-src-head mailing list