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