svn commit: r281369 - in head/sys/arm: arm include

Ian Lepore ian at FreeBSD.org
Fri Apr 10 13:26:38 UTC 2015


Author: ian
Date: Fri Apr 10 13:26:35 2015
New Revision: 281369
URL: https://svnweb.freebsd.org/changeset/base/281369

Log:
  Add a pmap_kremove_device() to undo mappings made with pmap_kenter_device().
  
  Previously we used pmap_kremove(), but with ARM_NEW_PMAP it does the remove
  in a way that isn't SMP-coherent (which is appropriate in some circumstances
  such as mapping/unmapping sf buffers).  With matching enter/remove routines
  for device mappings, each low-level implementation can do the right thing.
  
  Reviewed by:	Svatopluk Kraus <onwahe at gmail.com>

Modified:
  head/sys/arm/arm/devmap.c
  head/sys/arm/arm/pmap-v6-new.c
  head/sys/arm/arm/pmap-v6.c
  head/sys/arm/arm/pmap.c
  head/sys/arm/include/pmap-v6.h
  head/sys/arm/include/pmap.h

Modified: head/sys/arm/arm/devmap.c
==============================================================================
--- head/sys/arm/arm/devmap.c	Fri Apr 10 13:26:05 2015	(r281368)
+++ head/sys/arm/arm/devmap.c	Fri Apr 10 13:26:35 2015	(r281369)
@@ -246,7 +246,7 @@ arm_devmap_vtop(void * vpva, vm_size_t s
 void *
 pmap_mapdev(vm_offset_t pa, vm_size_t size)
 {
-	vm_offset_t va, tmpva, offset;
+	vm_offset_t va, offset;
 	void * rva;
 
 	/* First look in the static mapping table. */
@@ -261,12 +261,7 @@ pmap_mapdev(vm_offset_t pa, vm_size_t si
 	if (!va)
 		panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
 
-	for (tmpva = va; size > 0;) {
-		pmap_kenter_device(tmpva, pa);
-		size -= PAGE_SIZE;
-		tmpva += PAGE_SIZE;
-		pa += PAGE_SIZE;
-	}
+	pmap_kenter_device(va, size, pa);
 	
 	return ((void *)(va + offset));
 }
@@ -277,25 +272,18 @@ pmap_mapdev(vm_offset_t pa, vm_size_t si
 void
 pmap_unmapdev(vm_offset_t va, vm_size_t size)
 {
-	vm_offset_t tmpva, offset;
-	vm_size_t origsize;
+	vm_offset_t offset;
 
 	/* Nothing to do if we find the mapping in the static table. */
 	if (arm_devmap_vtop((void*)va, size) != DEVMAP_PADDR_NOTFOUND)
 		return;
 
-	origsize = size;
 	offset = va & PAGE_MASK;
 	va = trunc_page(va);
 	size = round_page(size + offset);
 
-	for (tmpva = va; size > 0;) {
-		pmap_kremove(tmpva);
-		size -= PAGE_SIZE;
-		tmpva += PAGE_SIZE;
-	}
-
-	kva_free(va, origsize);
+	pmap_kremove_device(va, size);
+	kva_free(va, size);
 }
 
 #ifdef DDB

Modified: head/sys/arm/arm/pmap-v6-new.c
==============================================================================
--- head/sys/arm/arm/pmap-v6-new.c	Fri Apr 10 13:26:05 2015	(r281368)
+++ head/sys/arm/arm/pmap-v6-new.c	Fri Apr 10 13:26:35 2015	(r281369)
@@ -6051,11 +6051,38 @@ retry:
 }
 
 void
-pmap_kenter_device(vm_offset_t va, vm_paddr_t pa)
+pmap_kenter_device(vm_offset_t va, vm_size_t size, vm_paddr_t pa)
 {
+	vm_offset_t sva;
 
-	pmap_kenter_prot_attr(va, pa, PTE2_AP_KRW, PTE2_ATTR_DEVICE);
-	tlb_flush(va);
+	KASSERT((size & PAGE_MASK) == 0, 
+	    ("%s: device mapping not page-sized", __func__));
+
+	sva = va;
+	while (size != 0) {
+		pmap_kenter_prot_attr(va, pa, PTE2_AP_KRW, PTE2_ATTR_DEVICE);
+		va += PAGE_SIZE;
+		pa += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+	tlb_flush_range(sva, va - sva);
+}
+
+void
+pmap_kremove_device(vm_offset_t va, vm_size_t size)
+{
+	vm_offset_t sva;
+
+	KASSERT((size & PAGE_MASK) == 0, 
+	    ("%s: device mapping not page-sized", __func__));
+
+	sva = va;
+	while (size != 0) {
+		pmap_kremove(va);
+		va += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+	tlb_flush_range(sva, va - sva);
 }
 
 void

Modified: head/sys/arm/arm/pmap-v6.c
==============================================================================
--- head/sys/arm/arm/pmap-v6.c	Fri Apr 10 13:26:05 2015	(r281368)
+++ head/sys/arm/arm/pmap-v6.c	Fri Apr 10 13:26:35 2015	(r281369)
@@ -2451,10 +2451,36 @@ pmap_kenter_nocache(vm_offset_t va, vm_p
 }
 
 void
-pmap_kenter_device(vm_offset_t va, vm_paddr_t pa)
+pmap_kenter_device(vm_offset_t va, vm_size_t size, vm_paddr_t pa)
 {
+	vm_offset_t sva;
 
-	pmap_kenter_internal(va, pa, KENTER_DEVICE);
+	KASSERT((size & PAGE_MASK) == 0, 
+	    ("%s: device mapping not page-sized", __func__));
+
+	sva = va;
+	while (size != 0) {
+		pmap_kenter_internal(va, pa, KENTER_DEVICE);
+		va += PAGE_SIZE;
+		pa += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+}
+
+void
+pmap_kremove_device(vm_offset_t va, vm_size_t size)
+{
+	vm_offset_t sva;
+
+	KASSERT((size & PAGE_MASK) == 0, 
+	    ("%s: device mapping not page-sized", __func__));
+
+	sva = va;
+	while (size != 0) {
+		pmap_kremove(va);
+		va += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
 }
 
 void

Modified: head/sys/arm/arm/pmap.c
==============================================================================
--- head/sys/arm/arm/pmap.c	Fri Apr 10 13:26:05 2015	(r281368)
+++ head/sys/arm/arm/pmap.c	Fri Apr 10 13:26:35 2015	(r281369)
@@ -2712,14 +2712,36 @@ pmap_kenter_nocache(vm_offset_t va, vm_p
 }
 
 void
-pmap_kenter_device(vm_offset_t va, vm_paddr_t pa)
+pmap_kenter_device(vm_offset_t va, vm_size_t size, vm_paddr_t pa)
 {
+	vm_offset_t sva;
 
-	/*
-	 * XXX - Need a way for kenter_internal to handle PTE_DEVICE mapping as
-	 * a potentially different thing than PTE_NOCACHE.
-	 */
-	pmap_kenter_internal(va, pa, 0);
+	KASSERT((size & PAGE_MASK) == 0, 
+	    ("%s: device mapping not page-sized", __func__));
+
+	sva = va;
+	while (size != 0) {
+		pmap_kenter_internal(va, pa, 0);
+		va += PAGE_SIZE;
+		pa += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+}
+
+void
+pmap_kremove_device(vm_offset_t va, vm_size_t size)
+{
+	vm_offset_t sva;
+
+	KASSERT((size & PAGE_MASK) == 0, 
+	    ("%s: device mapping not page-sized", __func__));
+
+	sva = va;
+	while (size != 0) {
+		pmap_kremove(va);
+		va += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
 }
 
 void

Modified: head/sys/arm/include/pmap-v6.h
==============================================================================
--- head/sys/arm/include/pmap-v6.h	Fri Apr 10 13:26:05 2015	(r281368)
+++ head/sys/arm/include/pmap-v6.h	Fri Apr 10 13:26:35 2015	(r281369)
@@ -190,7 +190,8 @@ void *pmap_mapdev_attr(vm_paddr_t, vm_si
 boolean_t pmap_page_is_mapped(vm_page_t );
 void pmap_page_set_memattr(vm_page_t , vm_memattr_t );
 void pmap_unmapdev(vm_offset_t, vm_size_t);
-void pmap_kenter_device(vm_offset_t , vm_paddr_t );
+void pmap_kenter_device(vm_offset_t, vm_size_t, vm_paddr_t);
+void pmap_kremove_device(vm_offset_t, vm_size_t);
 void pmap_set_pcb_pagedir(pmap_t , struct pcb *);
 void pmap_lazyfix_action(void);
 

Modified: head/sys/arm/include/pmap.h
==============================================================================
--- head/sys/arm/include/pmap.h	Fri Apr 10 13:26:05 2015	(r281368)
+++ head/sys/arm/include/pmap.h	Fri Apr 10 13:26:35 2015	(r281369)
@@ -258,7 +258,8 @@ void	pmap_bootstrap(vm_offset_t firstadd
 int	pmap_change_attr(vm_offset_t, vm_size_t, int);
 void	pmap_kenter(vm_offset_t va, vm_paddr_t pa);
 void	pmap_kenter_nocache(vm_offset_t va, vm_paddr_t pa);
-void	pmap_kenter_device(vm_offset_t va, vm_paddr_t pa);
+void	pmap_kenter_device(vm_offset_t, vm_size_t, vm_paddr_t);
+void	pmap_kremove_device(vm_offset_t, vm_size_t);
 void	*pmap_kenter_temporary(vm_paddr_t pa, int i);
 void 	pmap_kenter_user(vm_offset_t va, vm_paddr_t pa);
 vm_paddr_t pmap_kextract(vm_offset_t va);


More information about the svn-src-head mailing list