PERFORCE change 33673 for review

Peter Wemm peter at FreeBSD.org
Wed Jun 25 17:41:15 PDT 2003


http://perforce.freebsd.org/chv.cgi?CH=33673

Change 33673 by peter at peter_hammer on 2003/06/25 17:40:15

	We can only use the direct map region for pmap_mapdev() if
	the region we are trying to map is within the window.

Affected files ...

.. //depot/projects/hammer/sys/amd64/amd64/pmap.c#19 edit

Differences ...

==== //depot/projects/hammer/sys/amd64/amd64/pmap.c#19 (text+ko) ====

@@ -169,6 +169,7 @@
 
 static int nkpt;
 static int ndmpdp;
+static vm_paddr_t dmaplimit;
 vm_offset_t kernel_vm_end;
 
 static u_int64_t	KPTphys;	/* phys addr of kernel level 1 */
@@ -371,6 +372,7 @@
 		ndmpdp = 4;
 	DMPDPphys = allocpages(NDMPML4E);
 	DMPDphys = allocpages(ndmpdp);
+	dmaplimit = (vm_paddr_t)ndmpdp << PDPSHIFT;
 
 	/* Fill in the underlying page table pages */
 	/* Read-only from zero to physfree */
@@ -2868,7 +2870,25 @@
 	vm_paddr_t pa;
 	vm_size_t size;
 {
-	return (void *)PHYS_TO_DMAP(pa);
+	vm_offset_t va, tmpva, offset;
+
+	/* If this fits within the direct map window, use it */
+	if (pa < dmaplimit && (pa + size) < dmaplimit)
+		return ((void *)PHYS_TO_DMAP(pa));
+	offset = pa & PAGE_MASK;
+	size = roundup(offset + size, PAGE_SIZE);
+	va = kmem_alloc_pageable(kernel_map, size);
+	if (!va)
+		panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
+	pa = pa & PG_FRAME;
+	for (tmpva = va; size > 0; ) {
+		pmap_kenter(tmpva, pa);
+		size -= PAGE_SIZE;
+		tmpva += PAGE_SIZE;
+		pa += PAGE_SIZE;
+	}
+	pmap_invalidate_range(kernel_pmap, va, tmpva);
+	return ((void *)(va + offset));
 }
 
 void
@@ -2876,6 +2896,21 @@
 	vm_offset_t va;
 	vm_size_t size;
 {
+	vm_offset_t base, offset, tmpva;
+	pt_entry_t *pte;
+
+	/* If we gave a direct map region in pmap_mapdev, do nothing */
+        if (va >= DMAP_MIN_ADDRESS && va < DMAP_MAX_ADDRESS)
+		return;
+	base = va & PG_FRAME;
+	offset = va & PAGE_MASK;
+	size = roundup(offset + size, PAGE_SIZE);
+	for (tmpva = base; tmpva < (base + size); tmpva += PAGE_SIZE) {
+		pte = vtopte(tmpva);
+		pte_clear(pte);
+	}
+	pmap_invalidate_range(kernel_pmap, va, tmpva);
+	kmem_free(kernel_map, base, size);
 }
 
 /*


More information about the p4-projects mailing list