Module Name:    src
Committed By:   maxv
Date:           Wed Oct 18 17:12:42 UTC 2017

Modified Files:
        src/sys/arch/amd64/stand/prekern: mm.c

Log Message:
If a branch is already there, use it and don't create a new one. This way
we can call mm_map_tree twice with neighboring regions.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/amd64/stand/prekern/mm.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amd64/stand/prekern/mm.c
diff -u src/sys/arch/amd64/stand/prekern/mm.c:1.2 src/sys/arch/amd64/stand/prekern/mm.c:1.3
--- src/sys/arch/amd64/stand/prekern/mm.c:1.2	Sun Oct 15 06:37:32 2017
+++ src/sys/arch/amd64/stand/prekern/mm.c	Wed Oct 18 17:12:42 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mm.c,v 1.2 2017/10/15 06:37:32 maxv Exp $	*/
+/*	$NetBSD: mm.c,v 1.3 2017/10/18 17:12:42 maxv Exp $	*/
 
 /*
  * Copyright (c) 2017 The NetBSD Foundation, Inc. All rights reserved.
@@ -82,6 +82,12 @@ mm_palloc(size_t npages)
 	return pa;
 }
 
+static bool
+mm_pte_is_valid(pt_entry_t pte)
+{
+	return ((pte & PG_V) != 0);
+}
+
 paddr_t
 mm_vatopa(vaddr_t va)
 {
@@ -111,39 +117,46 @@ mm_map_tree(vaddr_t startva, vaddr_t end
 {
 	size_t i, size, nL4e, nL3e, nL2e;
 	size_t L4e_idx, L3e_idx, L2e_idx;
-	paddr_t L3page_pa, L2page_pa, L1page_pa;
+	paddr_t pa;
+
+	size = endva - startva;
 
 	/*
-	 * Initialize constants.
+	 * Build L4.
 	 */
-	size = endva - startva;
-	nL4e = roundup(size, NBPD_L4) / NBPD_L4;
-	nL3e = roundup(size, NBPD_L3) / NBPD_L3;
-	nL2e = roundup(size, NBPD_L2) / NBPD_L2;
 	L4e_idx = pl4_i(startva);
-	L3e_idx = pl3_i(startva);
-	L2e_idx = pl2_i(startva);
-
-	ASSERT(nL4e == 1);
+	nL4e = roundup(size, NBPD_L4) / NBPD_L4;
 	ASSERT(L4e_idx == 511);
+	ASSERT(nL4e == 1);
+	if (!mm_pte_is_valid(L4_BASE[L4e_idx])) {
+		pa = mm_palloc(1);
+		L4_BASE[L4e_idx] = pa | PG_V | PG_RW;
+	}
 
 	/*
-	 * Allocate the physical pages.
+	 * Build L3.
 	 */
-	L3page_pa = mm_palloc(nL4e);
-	L2page_pa = mm_palloc(nL3e);
-	L1page_pa = mm_palloc(nL2e);
+	L3e_idx = pl3_i(startva);
+	nL3e = roundup(size, NBPD_L3) / NBPD_L3;
+	for (i = 0; i < nL3e; i++) {
+		if (mm_pte_is_valid(L3_BASE[L3e_idx+i])) {
+			continue;
+		}
+		pa = mm_palloc(1);
+		L3_BASE[L3e_idx+i] = pa | PG_V | PG_RW;
+	}
 
 	/*
-	 * Build the branch in the page tree. We link the levels together,
-	 * from L4 to L1.
+	 * Build L2.
 	 */
-	L4_BASE[L4e_idx] = L3page_pa | PG_V | PG_RW;
-	for (i = 0; i < nL3e; i++) {
-		L3_BASE[L3e_idx+i] = (L2page_pa + i * PAGE_SIZE) | PG_V | PG_RW;
-	}
+	L2e_idx = pl2_i(startva);
+	nL2e = roundup(size, NBPD_L2) / NBPD_L2;
 	for (i = 0; i < nL2e; i++) {
-		L2_BASE[L2e_idx+i] = (L1page_pa + i * PAGE_SIZE) | PG_V | PG_RW;
+		if (mm_pte_is_valid(L2_BASE[L2e_idx+i])) {
+			continue;
+		}
+		pa = mm_palloc(1);
+		L2_BASE[L2e_idx+i] = pa | PG_V | PG_RW;
 	}
 }
 

Reply via email to