svn commit: r291246 - in head/sys/arm64: arm64 include

Andrew Turner andrew at FreeBSD.org
Tue Nov 24 11:01:44 UTC 2015


Author: andrew
Date: Tue Nov 24 11:01:43 2015
New Revision: 291246
URL: https://svnweb.freebsd.org/changeset/base/291246

Log:
  Add support for moving the DMAP range. This is needed as some AMD SoCs
  place physical memory at an address outside the old DMAP range. This is an
  issue as we rely on being able to move from PA -> VA using this range.
  
  Obtained from:	Patrick Wildt <patrick at bitrig.org> (earlier version)
  Sponsored by:	ABT Systems Ltd
  Differential Revision:	https://reviews.freebsd.org/D3885

Modified:
  head/sys/arm64/arm64/pmap.c
  head/sys/arm64/include/vmparam.h

Modified: head/sys/arm64/arm64/pmap.c
==============================================================================
--- head/sys/arm64/arm64/pmap.c	Tue Nov 24 09:52:46 2015	(r291245)
+++ head/sys/arm64/arm64/pmap.c	Tue Nov 24 11:01:43 2015	(r291246)
@@ -215,6 +215,8 @@ struct msgbuf *msgbufp = NULL;
 
 static struct rwlock_padalign pvh_global_lock;
 
+vm_paddr_t dmap_phys_base;	/* The start of the dmap region */
+
 /*
  * Data for the pv entry allocation mechanism
  */
@@ -446,18 +448,19 @@ pmap_early_vtophys(vm_offset_t l1pt, vm_
 }
 
 static void
-pmap_bootstrap_dmap(vm_offset_t l1pt)
+pmap_bootstrap_dmap(vm_offset_t l1pt, vm_paddr_t kernstart)
 {
 	vm_offset_t va;
 	vm_paddr_t pa;
 	pd_entry_t *l1;
 	u_int l1_slot;
 
+	pa = dmap_phys_base = kernstart & ~L1_OFFSET;
 	va = DMAP_MIN_ADDRESS;
 	l1 = (pd_entry_t *)l1pt;
 	l1_slot = pmap_l1_index(DMAP_MIN_ADDRESS);
 
-	for (pa = 0; va < DMAP_MAX_ADDRESS;
+	for (; va < DMAP_MAX_ADDRESS;
 	    pa += L1_SIZE, va += L1_SIZE, l1_slot++) {
 		KASSERT(l1_slot < Ln_ENTRIES, ("Invalid L1 index"));
 
@@ -548,7 +551,8 @@ pmap_bootstrap(vm_offset_t l1pt, vm_padd
 	pt_entry_t *l2;
 	vm_offset_t va, freemempos;
 	vm_offset_t dpcpu, msgbufpv;
-	vm_paddr_t pa;
+	vm_paddr_t pa, min_pa;
+	int i;
 
 	kern_delta = KERNBASE - kernstart;
 	physmem = 0;
@@ -566,8 +570,23 @@ pmap_bootstrap(vm_offset_t l1pt, vm_padd
 	 */
 	rw_init(&pvh_global_lock, "pmap pv global");
 
+	/* Assume the address we were loaded to is a valid physical address */
+	min_pa = KERNBASE - kern_delta;
+
+	/*
+	 * Find the minimum physical address. physmap is sorted,
+	 * but may contain empty ranges.
+	 */
+	for (i = 0; i < (physmap_idx * 2); i += 2) {
+		if (physmap[i] == physmap[i + 1])
+			continue;
+		if (physmap[i] <= min_pa)
+			min_pa = physmap[i];
+		break;
+	}
+
 	/* Create a direct map region early so we can use it for pa -> va */
-	pmap_bootstrap_dmap(l1pt);
+	pmap_bootstrap_dmap(l1pt, min_pa);
 
 	va = KERNBASE;
 	pa = KERNBASE - kern_delta;

Modified: head/sys/arm64/include/vmparam.h
==============================================================================
--- head/sys/arm64/include/vmparam.h	Tue Nov 24 09:52:46 2015	(r291245)
+++ head/sys/arm64/include/vmparam.h	Tue Nov 24 11:01:43 2015	(r291246)
@@ -160,11 +160,13 @@
 #define	DMAP_MIN_ADDRESS	(0xffffffc000000000UL)
 #define	DMAP_MAX_ADDRESS	(0xffffffdfffffffffUL)
 
-#define	DMAP_MIN_PHYSADDR	(0x0000000000000000UL)
-#define	DMAP_MAX_PHYSADDR	(DMAP_MAX_ADDRESS - DMAP_MIN_ADDRESS)
+extern vm_paddr_t dmap_phys_base;
+#define	DMAP_MIN_PHYSADDR	(dmap_phys_base)
+#define	DMAP_MAX_PHYSADDR	(dmap_phys_base + (DMAP_MAX_ADDRESS - DMAP_MIN_ADDRESS))
 
 /* True if pa is in the dmap range */
-#define	PHYS_IN_DMAP(pa)	((pa) <= DMAP_MAX_PHYSADDR)
+#define	PHYS_IN_DMAP(pa)	((pa) >= DMAP_MIN_PHYSADDR && \
+    (pa) <= DMAP_MAX_PHYSADDR)
 /* True if va is in the dmap range */
 #define	VIRT_IN_DMAP(va)	((va) >= DMAP_MIN_ADDRESS && \
     (va) <= DMAP_MAX_ADDRESS)
@@ -174,7 +176,7 @@
 	KASSERT(PHYS_IN_DMAP(pa),					\
 	    ("%s: PA out of range, PA: 0x%lx", __func__,		\
 	    (vm_paddr_t)(pa)));						\
-	(pa) | DMAP_MIN_ADDRESS;					\
+	((pa) - dmap_phys_base) | DMAP_MIN_ADDRESS;			\
 })
 
 #define	DMAP_TO_PHYS(va)						\
@@ -182,7 +184,7 @@
 	KASSERT(VIRT_IN_DMAP(va),					\
 	    ("%s: VA out of range, VA: 0x%lx", __func__,		\
 	    (vm_offset_t)(va)));					\
-	(va) & ~DMAP_MIN_ADDRESS;					\
+	((va) & ~DMAP_MIN_ADDRESS) + dmap_phys_base;			\
 })
 
 #define	VM_MIN_USER_ADDRESS	(0x0000000000000000UL)


More information about the svn-src-all mailing list