git: ba3b60200191 - main - Split out creating the arm64 L2 dmap entries
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 10 Mar 2022 18:17:22 UTC
The branch main has been updated by andrew:
URL: https://cgit.FreeBSD.org/src/commit/?id=ba3b60200191399c3c128e9acee47b5254514822
commit ba3b60200191399c3c128e9acee47b5254514822
Author: Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2022-03-10 18:00:40 +0000
Commit: Andrew Turner <andrew@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) {