Port-arm archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Raspberry Pi 3B: /dev/mem mmap GPIO works on earmv7hf but not onaarch64
I didn’t look at the patch in detail, but if you insist on doing this then you need to provide diffs that make it work for
GENERIC64_PMAPMI:options PMAP_MI
as well.
I intend to retire sys/arch/aarch64/aarch64/pmap.c
> On 25 Mar 2026, at 16:49, Izumi Tsutsui <tsutsui%ceres.dti.ne.jp@localhost> wrote:
>
> I wrote:
>
>> On the other hand, pmap_mmap_flags() (which is undocumented in pmap(9))
>> exists, at least on aarch64 and x86, and looks like a place where
>> mapping attributes for mmap(2) could be decided.
>
> The following changes against aarch64 specific pmap_mmap_flags()
> makes "mmap(2) GPIO via /dev/mem" work:
>
> https://github.com/tsutsui/netbsd-src/commit/567111726df3fd5180ac7a81266be9fefa2c6ce4
>
> ---
> aarch64: fix /dev/mem mmap cookie handling for MMIO devices
>
> On aarch64, /dev/mem mmap(2) commonly returns an mmap cookie
> without explicit MD ARM_MMAP_* attribute bits (nflag == 0) because
> there is no MD hook in current MI mem(4) implementation.
>
> In that case the mapping may end up as normal cacheable memory,
> which breaks MMIO register access.
>
> Adjust aarch64_mmap_flags(mdpgno) to return PMAP_DEV_NP only for
> the narrow case where:
>
> - AARCH64_MMAP_* bits are 0
> (note AARCH64_MMAP_WRITEBACK is also 0 so "unspecified" is ambiguous),
> - the PA is unmanaged (PHYS_TO_VM_PAGE(pa) == NULL), and
> - the PA is within a devmap region (pmap_devmap_find_pa() != NULL).
>
> Explicit cookie attributes (DEVICE, WRITECOMBINE, NOCACHE, and
> WRITEBACK against managed or non-devmap memory) are still decoded
> as before.
> ---
>
> diff --git a/sys/arch/aarch64/aarch64/pmap.c b/sys/arch/aarch64/aarch64/pmap.c
> index 53063d9dc92f..cff9859d5b8e 100644
> --- a/sys/arch/aarch64/aarch64/pmap.c
> +++ b/sys/arch/aarch64/aarch64/pmap.c
> @@ -2755,6 +2755,59 @@ pmap_is_referenced(struct vm_page *pg)
> return false;
> }
>
> +u_int
> +aarch64_mmap_flags(paddr_t mdpgno)
> +{
> + u_int nflag, pflag;
> + paddr_t pa;
> +
> + /*
> + * aarch64 arch has 5 memory attributes defined:
> + *
> + * WriteBack - write back cache
> + * WriteThru - write through cache
> + * NoCache - no cache
> + * Device(nGnRE) - no Gathering, no Reordering, Early write ack
> + * Device(nGnRnE) - no Gathering, no Reordering, no Early write ack
> + *
> + * but pmap has PMAP_{NOCACHE,WRITE_COMBINE,WRITE_BACK} flags.
> + */
> +
> + nflag = (mdpgno >> AARCH64_MMAP_FLAG_SHIFT) & AARCH64_MMAP_FLAG_MASK;
> +
> + /*
> + * If AARCH64_MMAP_FLAG is 0 (i.e. no way to distinguish explicit
> + * AARCH64_MMAP_WRITEBACK from "0" as "not specified"),
> + * the specified page is unmanaged and is within devmap region,
> + * assume MMIO device mappings.
> + */
> + pa = pmap_phys_address(mdpgno);
> + if (nflag == 0 &&
> + PHYS_TO_VM_PAGE(pa) == NULL &&
> + pmap_devmap_find_pa(pa, PAGE_SIZE) != NULL) {
> + return PMAP_DEV_NP;
> + }
> +
> + switch (nflag) {
> + case AARCH64_MMAP_DEVICE:
> + pflag = PMAP_DEV;
> + break;
> + case AARCH64_MMAP_WRITECOMBINE:
> + pflag = PMAP_WRITE_COMBINE;
> + break;
> + case AARCH64_MMAP_WRITEBACK:
> + pflag = PMAP_WRITE_BACK;
> + break;
> + case AARCH64_MMAP_NOCACHE:
> + pflag = PMAP_NOCACHE;
> + break;
> + default:
> + pflag = PMAP_NOCACHE;
> + break;
> + }
> + return pflag;
> +}
> +
> /* get pointer to kernel segment L2 or L3 table entry */
> pt_entry_t *
> kvtopte(vaddr_t va)
> diff --git a/sys/arch/aarch64/include/pmap.h b/sys/arch/aarch64/include/pmap.h
> index 3721dcac4dfe..6103d40e479b 100644
> --- a/sys/arch/aarch64/include/pmap.h
> +++ b/sys/arch/aarch64/include/pmap.h
> @@ -189,41 +189,7 @@ paddr_t vtophys(vaddr_t);
> #define PMAP_DEV_NP 0x40000000 /* kenter_pa */
> #define PMAP_DEV_MASK (PMAP_DEV | PMAP_DEV_NP)
>
> -static inline u_int
> -aarch64_mmap_flags(paddr_t mdpgno)
> -{
> - u_int nflag, pflag;
> -
> - /*
> - * aarch64 arch has 5 memory attributes defined:
> - *
> - * WriteBack - write back cache
> - * WriteThru - write through cache
> - * NoCache - no cache
> - * Device(nGnRE) - no Gathering, no Reordering, Early write ack
> - * Device(nGnRnE) - no Gathering, no Reordering, no Early write ack
> - *
> - * but pmap has PMAP_{NOCACHE,WRITE_COMBINE,WRITE_BACK} flags.
> - */
> -
> - nflag = (mdpgno >> AARCH64_MMAP_FLAG_SHIFT) & AARCH64_MMAP_FLAG_MASK;
> - switch (nflag) {
> - case AARCH64_MMAP_DEVICE:
> - pflag = PMAP_DEV;
> - break;
> - case AARCH64_MMAP_WRITECOMBINE:
> - pflag = PMAP_WRITE_COMBINE;
> - break;
> - case AARCH64_MMAP_WRITEBACK:
> - pflag = PMAP_WRITE_BACK;
> - break;
> - case AARCH64_MMAP_NOCACHE:
> - default:
> - pflag = PMAP_NOCACHE;
> - break;
> - }
> - return pflag;
> -}
> +u_int aarch64_mmap_flags(paddr_t);
>
> #define pmap_phys_address(ppn) aarch64_ptob((ppn) & ~ARM_MMAP_MASK)
> #define pmap_mmap_flags(ppn) aarch64_mmap_flags((ppn))
>
> ---
> (moved from pmap.h to pmap.c because it's a bit complicated to use
> PHYS_TO_VM_PAGE() (requires <uvm/uvm_page.h>) in an inline function)
>
>
> The following additional change is just for readability:
>
> https://github.com/tsutsui/netbsd-src/commit/0abc3913ad412488a74c3360bc951d16be034e6d
>
> ---
> aarch64/pmap: explicitly strip ARM_MMAP_* bits in pmap_phys_address()
>
> ARM_MMAP_* bits are placed higher bits in mdpgno so they will implicitly
> be dropped after aarch64_ptob() (i.e. << PGSHIFT) op, but it's
> a bit confusing for readers to depend on implementation details.
> ---
>
> diff --git a/sys/arch/aarch64/include/pmap.h b/sys/arch/aarch64/include/pmap.h
> index 52f909696cf8..3721dcac4dfe 100644
> --- a/sys/arch/aarch64/include/pmap.h
> +++ b/sys/arch/aarch64/include/pmap.h
> @@ -225,7 +225,7 @@ aarch64_mmap_flags(paddr_t mdpgno)
> return pflag;
> }
>
> -#define pmap_phys_address(pa) aarch64_ptob((pa))
> +#define pmap_phys_address(ppn) aarch64_ptob((ppn) & ~ARM_MMAP_MASK)
> #define pmap_mmap_flags(ppn) aarch64_mmap_flags((ppn))
>
> void pmap_bootstrap(vaddr_t, vaddr_t);
>
>
> ---
> Izumi Tsutsui
>
Home |
Main Index |
Thread Index |
Old Index