svn commit: r364447 - head/sys/powerpc/aim

Brandon Bergren bdragon at FreeBSD.org
Fri Aug 21 03:31:02 UTC 2020


Author: bdragon
Date: Fri Aug 21 03:31:01 2020
New Revision: 364447
URL: https://svnweb.freebsd.org/changeset/base/364447

Log:
  [PowerPC] Fix translation-related crashes during startup
  
  After spending a lot of time trying to track down what was going on, I have
  isolated the "black screen" failures when using boot1 to boot a G4 machine.
  
  It turns out we were replacing the traps before installing the temporary
  BAT entry for the bottom of physical memory. That meant that until the MMU
  was bootstrapped, the cached translations were the only thing keeping us
  from losing.
  
  Throwing boot1 into the mix was affecting execution flow enough to cause us
  to hit an uncached page and crash.
  
  Fix this by properly setting up the initial BAT entry at the same time we
  are replacing the OpenFirmware traps, so we can continue executing in
  segment 0 until the rest of the DMAP has been set up.
  
  A second thing discovered while researching this is that we were entering a
  BAT region for segment 16. It turns out this range was a) considered part
  of KVA, and b) has firmware mappings with varying attributes.
  
  If we ever accessed an unmapped page in segment 16, it would cause a BAT
  entry to be installed for the whole segment, which would bypass the
  existing mappings until it was flushed out again.
  
  Instead, translate the OFW memory attributes into VM memory attributes and
  install the ranges into the kernel address space properly.
  
  Reviewed by:	adalava
  MFC after:	3 weeks
  Sponsored by:	Tag1 Consulting, Inc.
  Differential Revision:	https://reviews.freebsd.org/D25547

Modified:
  head/sys/powerpc/aim/aim_machdep.c
  head/sys/powerpc/aim/mmu_oea.c

Modified: head/sys/powerpc/aim/aim_machdep.c
==============================================================================
--- head/sys/powerpc/aim/aim_machdep.c	Fri Aug 21 03:23:10 2020	(r364446)
+++ head/sys/powerpc/aim/aim_machdep.c	Fri Aug 21 03:31:01 2020	(r364447)
@@ -390,6 +390,25 @@ aim_cpu_init(vm_offset_t toc)
 		bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset);
 		bcopy(&restorebridge, (void *)EXC_TRC, trap_offset);
 		bcopy(&restorebridge, (void *)EXC_BPT, trap_offset);
+	} else {
+
+		/*
+		 * Use an IBAT and a DBAT to map the bottom 256M segment.
+		 *
+		 * It is very important to do it *now* to avoid taking a
+		 * fault in .text / .data before the MMU is bootstrapped,
+		 * because until then, the translation data has not been
+		 * copied over from OpenFirmware, so our DSI/ISI will fail
+		 * to find a match.
+		 */
+
+		battable[0x0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW);
+		battable[0x0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs);
+
+		__asm (".balign 32; \n"
+		    "mtibatu 0,%0; mtibatl 0,%1; isync; \n"
+		    "mtdbatu 0,%0; mtdbatl 0,%1; isync"
+		    :: "r"(battable[0].batu), "r"(battable[0].batl));
 	}
 	#else
 	trapsize = (size_t)&hypertrapcodeend - (size_t)&hypertrapcode;

Modified: head/sys/powerpc/aim/mmu_oea.c
==============================================================================
--- head/sys/powerpc/aim/mmu_oea.c	Fri Aug 21 03:23:10 2020	(r364446)
+++ head/sys/powerpc/aim/mmu_oea.c	Fri Aug 21 03:31:01 2020	(r364447)
@@ -420,6 +420,32 @@ moea_calc_wimg(vm_paddr_t pa, vm_memattr_t ma)
 	return pte_lo;
 }
 
+/*
+ * Translate OFW translations into VM attributes.
+ */
+static __inline vm_memattr_t
+moea_bootstrap_convert_wimg(uint32_t mode)
+{
+
+	switch (mode) {
+	case (PTE_I | PTE_G):
+		/* PCI device memory */
+		return VM_MEMATTR_UNCACHEABLE;
+	case (PTE_M):
+		/* Explicitly coherent */
+		return VM_MEMATTR_CACHEABLE;
+	case 0: /* Default claim */
+	case 2: /* Alternate PP bits set by OF for the original payload */
+		/* "Normal" memory. */
+		return VM_MEMATTR_DEFAULT;
+
+	default:
+		/* Err on the side of caution for unknowns */
+		/* XXX should we panic instead? */
+		return VM_MEMATTR_UNCACHEABLE;
+	}
+}
+
 static void
 tlbie(vm_offset_t va)
 {
@@ -670,14 +696,7 @@ moea_bootstrap(vm_offset_t kernelstart, vm_offset_t ke
 	vm_size_t	size, physsz, hwphyssz;
 	vm_offset_t	pa, va, off;
 	void		*dpcpu;
-	register_t	msr;
 
-        /*
-         * Set up BAT0 to map the lowest 256 MB area
-         */
-        battable[0x0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW);
-        battable[0x0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs);
-
 	/*
 	 * Map PCI memory space.
 	 */
@@ -693,25 +712,8 @@ moea_bootstrap(vm_offset_t kernelstart, vm_offset_t ke
 	battable[0xb].batl = BATL(0xb0000000, BAT_I|BAT_G, BAT_PP_RW);
 	battable[0xb].batu = BATU(0xb0000000, BAT_BL_256M, BAT_Vs);
 
-	/*
-	 * Map obio devices.
-	 */
-	battable[0xf].batl = BATL(0xf0000000, BAT_I|BAT_G, BAT_PP_RW);
-	battable[0xf].batu = BATU(0xf0000000, BAT_BL_256M, BAT_Vs);
+	powerpc_sync();
 
-	/*
-	 * Use an IBAT and a DBAT to map the bottom segment of memory
-	 * where we are. Turn off instruction relocation temporarily
-	 * to prevent faults while reprogramming the IBAT.
-	 */
-	msr = mfmsr();
-	mtmsr(msr & ~PSL_IR);
-	__asm (".balign 32; \n"
-	       "mtibatu 0,%0; mtibatl 0,%1; isync; \n"
-	       "mtdbatu 0,%0; mtdbatl 0,%1; isync"
-	    :: "r"(battable[0].batu), "r"(battable[0].batl));
-	mtmsr(msr);
-
 	/* map pci space */
 	__asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu));
 	__asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl));
@@ -910,15 +912,21 @@ moea_bootstrap(vm_offset_t kernelstart, vm_offset_t ke
 			/*
 			 * If the mapping is 1:1, let the RAM and device
 			 * on-demand BAT tables take care of the translation.
+			 *
+			 * However, always enter mappings for segment 16,
+			 * which is mixed-protection and therefore not
+			 * compatible with a BAT entry.
 			 */
-			if (translations[i].om_va == translations[i].om_pa)
-				continue;
+			if ((translations[i].om_va >> ADDR_SR_SHFT) != 0xf &&
+				translations[i].om_va == translations[i].om_pa)
+					continue;
 
 			/* Enter the pages */
 			for (off = 0; off < translations[i].om_len;
 			    off += PAGE_SIZE)
-				moea_kenter(translations[i].om_va + off,
-					    translations[i].om_pa + off);
+				moea_kenter_attr(translations[i].om_va + off,
+				    translations[i].om_pa + off,
+				    moea_bootstrap_convert_wimg(translations[i].om_mode));
 		}
 	}
 


More information about the svn-src-head mailing list