The branch main has been updated by andrew:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=ba3b60200191399c3c128e9acee47b5254514822

commit ba3b60200191399c3c128e9acee47b5254514822
Author:     Andrew Turner <and...@freebsd.org>
AuthorDate: 2022-03-10 18:00:40 +0000
Commit:     Andrew Turner <and...@freebsd.org>
CommitDate: 2022-03-10 18:17:06 +0000

    Split out creating the arm64 L2 dmap entries
    
    When creating the DMAP region we may need to create level 2 page table
    entries at the start and end of a block of memory. The code to do this
    was almost identical so we can merge into a single function.
    
    Sponsored by:   The FreeBSD Foundation
---
 sys/arm64/arm64/pmap.c | 113 +++++++++++++++++++++++--------------------------
 1 file changed, 54 insertions(+), 59 deletions(-)

diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index e3e6f9036dc2..c11a13e13866 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -803,14 +803,62 @@ pmap_early_vtophys(vm_offset_t va)
        return (pa_page | (va & PAR_LOW_MASK));
 }
 
+static vm_offset_t
+pmap_bootstrap_dmap_l2(vm_offset_t *va, vm_paddr_t *pa, u_int *prev_l1_slot,
+    pt_entry_t **l2p, int i, vm_offset_t freemempos)
+{
+       pt_entry_t *l2;
+       vm_paddr_t l2_pa;
+       u_int l1_slot, l2_slot;
+       bool first;
+
+       l2 = *l2p;
+       l1_slot = ((*va - DMAP_MIN_ADDRESS) >> L1_SHIFT);
+       if (l1_slot != *prev_l1_slot) {
+               *prev_l1_slot = l1_slot;
+               l2 = (pt_entry_t *)freemempos;
+               l2_pa = pmap_early_vtophys((vm_offset_t)l2);
+               freemempos += PAGE_SIZE;
+
+               pmap_store(&pagetable_dmap[l1_slot],
+                   (l2_pa & ~Ln_TABLE_MASK) |
+                   TATTR_PXN_TABLE | L1_TABLE);
+
+               memset(l2, 0, PAGE_SIZE);
+       }
+       KASSERT(l2 != NULL,
+           ("pmap_bootstrap_dmap_l2: NULL l2 map"));
+       for (first = true; *va < DMAP_MAX_ADDRESS && *pa < physmap[i + 1];
+           *pa += L2_SIZE, *va += L2_SIZE) {
+               /*
+                * Stop if we are about to walk off the end of what the
+                * current L1 slot can address.
+                */
+               if (!first && (*pa & L1_OFFSET) == 0)
+                       break;
+
+               first = false;
+               l2_slot = pmap_l2_index(*va);
+               pmap_store(&l2[l2_slot],
+                   (*pa & ~L2_OFFSET) | ATTR_DEFAULT |
+                   ATTR_S1_XN |
+                   ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) |
+                   L2_BLOCK);
+       }
+       MPASS(*va == (*pa - dmap_phys_base + DMAP_MIN_ADDRESS));
+       *l2p = l2;
+
+       return (freemempos);
+}
+
 static vm_offset_t
 pmap_bootstrap_dmap(vm_offset_t kern_l1, vm_paddr_t min_pa,
     vm_offset_t freemempos)
 {
        pt_entry_t *l2;
        vm_offset_t va;
-       vm_paddr_t l2_pa, pa;
-       u_int l1_slot, l2_slot, prev_l1_slot;
+       vm_paddr_t pa;
+       u_int l1_slot, prev_l1_slot;
        int i;
 
        dmap_phys_base = min_pa & ~L1_OFFSET;
@@ -828,40 +876,8 @@ pmap_bootstrap_dmap(vm_offset_t kern_l1, vm_paddr_t min_pa,
 
                /* Create L2 mappings at the start of the region */
                if ((pa & L1_OFFSET) != 0) {
-                       l1_slot = ((va - DMAP_MIN_ADDRESS) >> L1_SHIFT);
-                       if (l1_slot != prev_l1_slot) {
-                               prev_l1_slot = l1_slot;
-                               l2 = (pt_entry_t *)freemempos;
-                               l2_pa = pmap_early_vtophys((vm_offset_t)l2);
-                               freemempos += PAGE_SIZE;
-
-                               pmap_store(&pagetable_dmap[l1_slot],
-                                   (l2_pa & ~Ln_TABLE_MASK) |
-                                   TATTR_PXN_TABLE | L1_TABLE);
-
-                               memset(l2, 0, PAGE_SIZE);
-                       }
-                       KASSERT(l2 != NULL,
-                           ("pmap_bootstrap_dmap: NULL l2 map"));
-                       for (; va < DMAP_MAX_ADDRESS && pa < physmap[i + 1];
-                           pa += L2_SIZE, va += L2_SIZE) {
-                               /*
-                                * We are on a boundary, stop to
-                                * create a level 1 block
-                                */
-                               if ((pa & L1_OFFSET) == 0)
-                                       break;
-
-                               l2_slot = pmap_l2_index(va);
-                               KASSERT(l2_slot != 0, ("..."));
-                               pmap_store(&l2[l2_slot],
-                                   (pa & ~L2_OFFSET) | ATTR_DEFAULT |
-                                   ATTR_S1_XN |
-                                   ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) |
-                                   L2_BLOCK);
-                       }
-                       KASSERT(va == (pa - dmap_phys_base + DMAP_MIN_ADDRESS),
-                           ("..."));
+                       freemempos = pmap_bootstrap_dmap_l2(&va, &pa,
+                           &prev_l1_slot, &l2, i, freemempos);
                }
 
                for (; va < DMAP_MAX_ADDRESS && pa < physmap[i + 1] &&
@@ -875,29 +891,8 @@ pmap_bootstrap_dmap(vm_offset_t kern_l1, vm_paddr_t min_pa,
 
                /* Create L2 mappings at the end of the region */
                if (pa < physmap[i + 1]) {
-                       l1_slot = ((va - DMAP_MIN_ADDRESS) >> L1_SHIFT);
-                       if (l1_slot != prev_l1_slot) {
-                               prev_l1_slot = l1_slot;
-                               l2 = (pt_entry_t *)freemempos;
-                               l2_pa = pmap_early_vtophys((vm_offset_t)l2);
-                               freemempos += PAGE_SIZE;
-
-                               pmap_store(&pagetable_dmap[l1_slot],
-                                   (l2_pa & ~Ln_TABLE_MASK) | L1_TABLE);
-
-                               memset(l2, 0, PAGE_SIZE);
-                       }
-                       KASSERT(l2 != NULL,
-                           ("pmap_bootstrap_dmap: NULL l2 map"));
-                       for (; va < DMAP_MAX_ADDRESS && pa < physmap[i + 1];
-                           pa += L2_SIZE, va += L2_SIZE) {
-                               l2_slot = pmap_l2_index(va);
-                               pmap_store(&l2[l2_slot],
-                                   (pa & ~L2_OFFSET) | ATTR_DEFAULT |
-                                   ATTR_S1_XN |
-                                   ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) |
-                                   L2_BLOCK);
-                       }
+                       freemempos = pmap_bootstrap_dmap_l2(&va, &pa,
+                           &prev_l1_slot, &l2, i, freemempos);
                }
 
                if (pa > dmap_phys_max) {

Reply via email to