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) {