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; } }