svn commit: r213455 - in head/sys/i386: i386 include

Alan Cox alc at FreeBSD.org
Tue Oct 5 17:06:52 UTC 2010


Author: alc
Date: Tue Oct  5 17:06:51 2010
New Revision: 213455
URL: http://svn.freebsd.org/changeset/base/213455

Log:
  Initialize KPTmap in locore so that vm86.c can call vtophys() (or really
  pmap_kextract()) before pmap_bootstrap() is called.
  
  Document the set of pmap functions that may be called before
  pmap_bootstrap() is called.
  
  Tested by:	bde@
  Reviewed by:	kib@
  Discussed with:	jhb@
  MFC after:	6 weeks

Modified:
  head/sys/i386/i386/locore.s
  head/sys/i386/i386/pmap.c
  head/sys/i386/include/pmap.h

Modified: head/sys/i386/i386/locore.s
==============================================================================
--- head/sys/i386/i386/locore.s	Tue Oct  5 16:14:08 2010	(r213454)
+++ head/sys/i386/i386/locore.s	Tue Oct  5 17:06:51 2010	(r213455)
@@ -104,6 +104,9 @@ IdlePTD:	.long	0		/* phys addr of kernel
 IdlePDPT:	.long	0		/* phys addr of kernel PDPT */
 #endif
 
+	.globl	KPTmap
+KPTmap:		.long	0		/* address of kernel page tables */
+
 	.globl	KPTphys
 KPTphys:	.long	0		/* phys addr of kernel page tables */
 
@@ -715,6 +718,8 @@ no_kernend:
 /* Allocate Kernel Page Tables */
 	ALLOCPAGES(NKPT)
 	movl	%esi,R(KPTphys)
+	addl	$(KERNBASE-(KPTDI<<(PDRSHIFT-PAGE_SHIFT+PTESHIFT))),%esi
+	movl	%esi,R(KPTmap)
 
 /* Allocate Page Table Directory */
 #ifdef PAE
@@ -778,6 +783,11 @@ no_kernend:
 	shrl	$PAGE_SHIFT,%ecx
 	fillkptphys($PG_RW)
 
+/* Map page table pages. */
+	movl	R(KPTphys),%eax
+	movl	$NKPT,%ecx
+	fillkptphys($PG_RW)
+
 /* Map page directory. */
 #ifdef PAE
 	movl	R(IdlePDPT), %eax

Modified: head/sys/i386/i386/pmap.c
==============================================================================
--- head/sys/i386/i386/pmap.c	Tue Oct  5 16:14:08 2010	(r213454)
+++ head/sys/i386/i386/pmap.c	Tue Oct  5 17:06:51 2010	(r213455)
@@ -247,7 +247,7 @@ struct sysmaps {
 	caddr_t	CADDR2;
 };
 static struct sysmaps sysmaps_pcpu[MAXCPU];
-pt_entry_t *CMAP1 = 0, *KPTmap;
+pt_entry_t *CMAP1 = 0;
 static pt_entry_t *CMAP3;
 static pd_entry_t *KPTD;
 caddr_t CADDR1 = 0, ptvmmap = 0;
@@ -362,12 +362,11 @@ pmap_bootstrap(vm_paddr_t firstaddr)
 	int i;
 
 	/*
-	 * XXX The calculation of virtual_avail is wrong. It's NKPT*PAGE_SIZE too
-	 * large. It should instead be correctly calculated in locore.s and
-	 * not based on 'first' (which is a physical address, not a virtual
-	 * address, for the start of unused physical memory). The kernel
-	 * page tables are NOT double mapped and thus should not be included
-	 * in this calculation.
+	 * Initialize the first available kernel virtual address.  However,
+	 * using "firstaddr" may waste a few pages of the kernel virtual
+	 * address space, because locore may not have mapped every physical
+	 * page that it allocated.  Preferably, locore would provide a first
+	 * unused virtual address in addition to "firstaddr".
 	 */
 	virtual_avail = (vm_offset_t) KERNBASE + firstaddr;
 
@@ -437,6 +436,10 @@ pmap_bootstrap(vm_paddr_t firstaddr)
 
 	/*
 	 * KPTmap is used by pmap_kextract().
+	 *
+	 * KPTmap is first initialized by locore.  However, that initial
+	 * KPTmap can only support NKPT page table pages.  Here, a larger
+	 * KPTmap is created that can support KVA_PAGES page table pages.
 	 */
 	SYSMAP(pt_entry_t *, KPTD, KPTmap, KVA_PAGES)
 
@@ -1386,6 +1389,8 @@ retry:
 /*
  * Add a wired page to the kva.
  * Note: not SMP coherent.
+ *
+ * This function may be used before pmap_bootstrap() is called.
  */
 PMAP_INLINE void 
 pmap_kenter(vm_offset_t va, vm_paddr_t pa)
@@ -1408,6 +1413,8 @@ pmap_kenter_attr(vm_offset_t va, vm_padd
 /*
  * Remove a page from the kernel pagetables.
  * Note: not SMP coherent.
+ *
+ * This function may be used before pmap_bootstrap() is called.
  */
 PMAP_INLINE void
 pmap_kremove(vm_offset_t va)

Modified: head/sys/i386/include/pmap.h
==============================================================================
--- head/sys/i386/include/pmap.h	Tue Oct  5 16:14:08 2010	(r213454)
+++ head/sys/i386/include/pmap.h	Tue Oct  5 17:06:51 2010	(r213455)
@@ -191,12 +191,21 @@ extern pdpt_entry_t *IdlePDPT;
 extern pd_entry_t *IdlePTD;	/* physical address of "Idle" state directory */
 
 /*
- * virtual address to page table entry and
- * to physical address.
- * Note: these work recursively, thus vtopte of a pte will give
- * the corresponding pde that in turn maps it.
+ * Translate a virtual address to the kernel virtual address of its page table
+ * entry (PTE).  This can be used recursively.  If the address of a PTE as
+ * previously returned by this macro is itself given as the argument, then the
+ * address of the page directory entry (PDE) that maps the PTE will be
+ * returned.
+ *
+ * This macro may be used before pmap_bootstrap() is called.
  */
 #define	vtopte(va)	(PTmap + i386_btop(va))
+
+/*
+ * Translate a virtual address to its physical address.
+ *
+ * This macro may be used before pmap_bootstrap() is called.
+ */
 #define	vtophys(va)	pmap_kextract((vm_offset_t)(va))
 
 #ifdef XEN
@@ -272,14 +281,18 @@ pte_load_store_ma(pt_entry_t *ptep, pt_e
  * table pages, and not user page table pages, and (2) it provides access to
  * a kernel page table page after the corresponding virtual addresses have
  * been promoted to a 2/4MB page mapping.
+ *
+ * KPTmap is first initialized by locore to support just NPKT page table
+ * pages.  Later, it is reinitialized by pmap_bootstrap() to allow for
+ * expansion of the kernel page table.
  */
 extern pt_entry_t *KPTmap;
 
 /*
- *	Routine:	pmap_kextract
- *	Function:
- *		Extract the physical page address associated
- *		kernel virtual address.
+ * Extract from the kernel page table the physical address that is mapped by
+ * the given virtual address "va".
+ *
+ * This function may be used before pmap_bootstrap() is called.
  */
 static __inline vm_paddr_t
 pmap_kextract(vm_offset_t va)
@@ -486,6 +499,11 @@ extern vm_offset_t virtual_end;
 #define	pmap_page_get_memattr(m)	((vm_memattr_t)(m)->md.pat_mode)
 #define	pmap_unmapbios(va, sz)	pmap_unmapdev((va), (sz))
 
+/*
+ * Only the following functions or macros may be used before pmap_bootstrap()
+ * is called: pmap_kenter(), pmap_kextract(), pmap_kremove(), vtophys(), and
+ * vtopte().
+ */
 void	pmap_bootstrap(vm_paddr_t);
 int	pmap_cache_bits(int mode, boolean_t is_pde);
 int	pmap_change_attr(vm_offset_t, vm_size_t, int);


More information about the svn-src-all mailing list