From nobody Mon Jan 26 14:53:57 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4f0BPd4Kmxz6QNJJ for ; Mon, 26 Jan 2026 14:53:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4f0BPd3DWtz3vRq for ; Mon, 26 Jan 2026 14:53:57 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1769439237; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=6iIUEakp06Evg2wIHZSHKP/eHq81718zP8BdlFD6/Os=; b=CebF84u3sSmCAbVw/j4masM4l/uT/T5A5ZjkLtutUCG5C0HBgmrtqPeVjk5+jaDe35ybRF Z/RXwLhYDoQViTiEaPG/2cQLk1Eb6DFFSDri5z5VznzwpHixJCPCuvInuYcbFFTyRCSE3f cJ+u/1K2thimDB/qlg1augVvBtUFhg16XFKIPVuXUmzzgauv92A4pd1D6XMYtvmfEddrs6 P/xy/VL+dQernRVTgxE4u0AKBefsTi9HcDMsK/P4I1GfC1lo1Xu87beszdpyoyyYoVnc0T NdtV3Aoh8GBO7Hh5HLAu3vq+r5p/lb0GcyXn4Xd9h2cGaNihC5JMlLBIiNDIpw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1769439237; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=6iIUEakp06Evg2wIHZSHKP/eHq81718zP8BdlFD6/Os=; b=UK+d2NtbgWBLAswLAX2GX+NaaetzXh7EY0FIZhJy7b6CdzcxOrWUdT2ruV4MwpzVEghYH8 5FJbygB5pM0YZ+iFfQGwmCDejC3BY3jWHGJadJX2gzkia1iSJgQTARNyIcBxu45eO8uafo IuU2wmhOrwOYolWk8PjLBEKrsJDaMvv1uTpcXXqh6V0HgaDm6Ap8iuHHQtcyEcmXBQCJVi kDFglV+p1+L4IxIsWLawCKEaCvj2b5Pl+h17RwHX7oQyRoHyaXXcUoEZYxNU6kU8oJa9Vo KMLUz7OZwt/M8295/vyV3hQw6waV5CyIJYzhx8iCKzzqpA2zGgqXZk/WSzUfiw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1769439237; a=rsa-sha256; cv=none; b=rZ6sC3DNHOgTGopID12d2naI59uEAJ+FOF1Ai64BsJkn8wqoELBTJCmOuaJ3GNu6pXUD8a a9LQ2kLVlTcrf1Napc0yYrE97uxGWMA57PVUNH8yzNh9QWv87MgnAkXjxymZEi3JRa8hCp padCovTxJdefZFIfjbjgL01s27OtAmj3m9M0g0iYfUtX7WOFtkSYowrPiJ/ujxt361e1cj LDlzmVAxjiGRM54zB7dUlNwdz8Vh7+oOGL5K3SsWh7Bnwx7gVVGpbleu/49kE0Tu5RNynk fS3yJVHfa+pQoUg2tng+NSX/0BgbWVpvWYNaBBp/bY9lG4B2OiIkIWReNSTsiQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4f0BPd2qxjz8Ww for ; Mon, 26 Jan 2026 14:53:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 32f61 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 26 Jan 2026 14:53:57 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mitchell Horne Subject: git: 27595bea6940 - main - riscv: smarter DMAP construction (again) List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mhorne X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 27595bea69400ae71fa778cf1dcb52a793911ad4 Auto-Submitted: auto-generated Date: Mon, 26 Jan 2026 14:53:57 +0000 Message-Id: <69778005.32f61.7f792292@gitrepo.freebsd.org> The branch main has been updated by mhorne: URL: https://cgit.FreeBSD.org/src/commit/?id=27595bea69400ae71fa778cf1dcb52a793911ad4 commit 27595bea69400ae71fa778cf1dcb52a793911ad4 Author: Mitchell Horne AuthorDate: 2026-01-21 18:58:01 +0000 Commit: Mitchell Horne CommitDate: 2026-01-26 14:50:56 +0000 riscv: smarter DMAP construction (again) Extend pmap_bootstrap_dmap() to build the DMAP with 4K-page granularity. Recently we have been approximating it with 2MB mappings. The motivation again is the problematic FU540 hardware, which seems to require more accurate mappings still to avoid triggering its PMP errata. Although this hardware alone is of little consequence, constructing the DMAP accurately/correctly may help avoid future surprises. The implementation contains some repetitive code. This could be expressed differently, but my guiding principle for these early routines is that being simple and explicit about what we are doing makes them easier to comprehend. See also 762a3224cde6 ("riscv: smarter DMAP construction). Tested by: Klaus Küchemann MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D54716 --- sys/riscv/riscv/pmap.c | 98 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 83 insertions(+), 15 deletions(-) diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c index 0deb8b93a6dc..3fc261a15c06 100644 --- a/sys/riscv/riscv/pmap.c +++ b/sys/riscv/riscv/pmap.c @@ -578,16 +578,13 @@ pmap_early_alloc_tables(vm_paddr_t *freemempos, int npages) } /* - * Construct the direct map -- a linear mapping of physical memory into + * Construct the Direct Map -- a linear mapping of physical memory into * the kernel address space. * * We walk the list of physical memory segments (of arbitrary size and - * address) mapping each appropriately using L2 and L1 superpages. - * Consequently, the DMAP address space will have unmapped regions - * corresponding to any holes between physical memory segments. - * - * The lowest usable physical address will always be mapped to - * DMAP_MIN_ADDRESS. + * alignment) mapping each appropriately. Consequently, the DMAP address + * space will have unmapped regions corresponding to the holes between + * physical memory segments. */ static vm_paddr_t pmap_bootstrap_dmap(pd_entry_t *l1, vm_paddr_t freemempos) @@ -595,9 +592,9 @@ pmap_bootstrap_dmap(pd_entry_t *l1, vm_paddr_t freemempos) vm_paddr_t physmap[PHYS_AVAIL_ENTRIES]; vm_offset_t va; vm_paddr_t min_pa, max_pa, pa, endpa; - pd_entry_t *l2; + pd_entry_t *l3, *l2; pt_entry_t memattr; - u_int l1slot, l2slot; + u_int l1slot, l2slot, l3slot; int physmap_idx; physmap_idx = physmem_avail(physmap, nitems(physmap)); @@ -614,17 +611,58 @@ pmap_bootstrap_dmap(pd_entry_t *l1, vm_paddr_t freemempos) memattr = pmap_memattr_bits(VM_MEMATTR_DEFAULT); - /* Walk the physmap table. */ - l2 = NULL; - l1slot = Ln_ENTRIES; /* sentinel value */ + /* + * Walk the physmap table, using the largest page sizes possible for each + * mapping. So, for each physmap entry, map as needed/able: + * - 4K/L3 page prefix + * - 2M/L2 superpage prefix + * - 1G/L1 superpages + * - 2M/L2 superpage suffix + * - 4K/L3 page suffix + */ + l3 = l2 = NULL; + l2slot = l1slot = Ln_ENTRIES; /* sentinel value */ for (int idx = 0; idx < physmap_idx; idx += 2) { - pa = rounddown(physmap[idx], L2_SIZE); + pa = rounddown(physmap[idx], L3_SIZE); endpa = physmap[idx + 1]; /* Virtual address for this range. */ va = PHYS_TO_DMAP(pa); - /* Any 1GB possible for this range? */ + /* Any 2MB possible for this range? */ + if (roundup(pa, L2_SIZE) + L2_SIZE > endpa) + goto l3end; + + /* Loop until the next 2MB boundary. */ + while ((pa & L2_OFFSET) != 0) { + if (l2 == NULL || pmap_l1_index(va) != l1slot) { + /* Need to alloc another page table. */ + l2 = pmap_early_alloc_tables(&freemempos, 1); + + /* Link it. */ + l1slot = pmap_l1_index(va); + pmap_store(&l1[l1slot], + L1_PDE((vm_paddr_t)l2, PTE_V)); + } + + if (l3 == NULL || pmap_l2_index(va) != l2slot) { + l3 = pmap_early_alloc_tables(&freemempos, 1); + + /* Link it to L2. */ + l2slot = pmap_l2_index(va); + pmap_store(&l2[l2slot], + L2_PDE((vm_paddr_t)l3, PTE_V)); + } + + /* map l3 pages */ + l3slot = pmap_l3_index(va); + pmap_store(&l3[l3slot], L3_PTE(pa, PTE_KERN | memattr)); + + pa += L3_SIZE; + va += L3_SIZE; + } + + /* Any 1GB possible for remaining range? */ if (roundup(pa, L1_SIZE) + L1_SIZE > endpa) goto l2end; @@ -659,7 +697,8 @@ pmap_bootstrap_dmap(pd_entry_t *l1, vm_paddr_t freemempos) } l2end: - while (pa < endpa) { + /* Map what we can with 2MB superpages. */ + while (pa + L2_SIZE - 1 < endpa) { if (l2 == NULL || pmap_l1_index(va) != l1slot) { /* Need to alloc another page table. */ l2 = pmap_early_alloc_tables(&freemempos, 1); @@ -677,6 +716,35 @@ l2end: pa += L2_SIZE; va += L2_SIZE; } + +l3end: + while (pa < endpa) { + if (l2 == NULL || pmap_l1_index(va) != l1slot) { + /* Need to alloc another page table. */ + l2 = pmap_early_alloc_tables(&freemempos, 1); + + /* Link it. */ + l1slot = pmap_l1_index(va); + pmap_store(&l1[l1slot], + L1_PDE((vm_paddr_t)l2, PTE_V)); + } + + if (l3 == NULL || pmap_l2_index(va) != l2slot) { + l3 = pmap_early_alloc_tables(&freemempos, 1); + + /* Link it to L2. */ + l2slot = pmap_l2_index(va); + pmap_store(&l2[l2slot], + L2_PDE((vm_paddr_t)l3, PTE_V)); + } + + /* map l3 pages */ + l3slot = pmap_l3_index(va); + pmap_store(&l3[l3slot], L3_PTE(pa, PTE_KERN | memattr)); + + pa += L3_SIZE; + va += L3_SIZE; + } } /* And finally, the limit on DMAP VA. */