Re: Raspberry Pi 3B: /dev/mem mmap GPIO works on earmv7hf but not onaarch64
Nick Hudson <[email protected]> Wed, 25 Mar 2026 17:41:48 +0000
| Newsgroups | gmane.os.netbsd.ports.arm |
|---|---|
| Message-ID | <[email protected]> |
I didn=E2=80=99t 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 <[email protected]> = wrote: >=20 > I wrote: >=20 >> On the other hand, pmap_mmap_flags() (which is undocumented in = pmap(9))=20 >> exists, at least on aarch64 and x86, and looks like a place where >> mapping attributes for mmap(2) could be decided. >=20 > The following changes against aarch64 specific pmap_mmap_flags() > makes "mmap(2) GPIO via /dev/mem" work: >=20 > = https://github.com/tsutsui/netbsd-src/commit/567111726df3fd5180ac7a81266be= 9fefa2c6ce4 >=20 > --- > aarch64: fix /dev/mem mmap cookie handling for MMIO devices >=20 > On aarch64, /dev/mem mmap(2) commonly returns an mmap cookie > without explicit MD ARM_MMAP_* attribute bits (nflag =3D=3D 0) because > there is no MD hook in current MI mem(4) implementation. >=20 > In that case the mapping may end up as normal cacheable memory, > which breaks MMIO register access. >=20 > Adjust aarch64_mmap_flags(mdpgno) to return PMAP_DEV_NP only for > the narrow case where: >=20 > - 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) =3D=3D NULL), and > - the PA is within a devmap region (pmap_devmap_find_pa() !=3D NULL). >=20 > Explicit cookie attributes (DEVICE, WRITECOMBINE, NOCACHE, and > WRITEBACK against managed or non-devmap memory) are still decoded > as before. > --- >=20 > 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; > } >=20 > +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 =3D (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 =3D pmap_phys_address(mdpgno); > + if (nflag =3D=3D 0 && > + PHYS_TO_VM_PAGE(pa) =3D=3D NULL && > + pmap_devmap_find_pa(pa, PAGE_SIZE) !=3D NULL) { > + return PMAP_DEV_NP; > + } > + > + switch (nflag) { > + case AARCH64_MMAP_DEVICE: > + pflag =3D PMAP_DEV; > + break; > + case AARCH64_MMAP_WRITECOMBINE: > + pflag =3D PMAP_WRITE_COMBINE; > + break; > + case AARCH64_MMAP_WRITEBACK: > + pflag =3D PMAP_WRITE_BACK; > + break; > + case AARCH64_MMAP_NOCACHE: > + pflag =3D PMAP_NOCACHE; > + break; > + default: > + pflag =3D 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) >=20 > -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 =3D (mdpgno >> AARCH64_MMAP_FLAG_SHIFT) & = AARCH64_MMAP_FLAG_MASK; > - switch (nflag) { > - case AARCH64_MMAP_DEVICE: > - pflag =3D PMAP_DEV; > - break; > - case AARCH64_MMAP_WRITECOMBINE: > - pflag =3D PMAP_WRITE_COMBINE; > - break; > - case AARCH64_MMAP_WRITEBACK: > - pflag =3D PMAP_WRITE_BACK; > - break; > - case AARCH64_MMAP_NOCACHE: > - default: > - pflag =3D PMAP_NOCACHE; > - break; > - } > - return pflag; > -} > +u_int aarch64_mmap_flags(paddr_t); >=20 > #define pmap_phys_address(ppn) aarch64_ptob((ppn) & ~ARM_MMAP_MASK) > #define pmap_mmap_flags(ppn) aarch64_mmap_flags((ppn)) >=20 > --- > (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) >=20 >=20 > The following additional change is just for readability: >=20 > = https://github.com/tsutsui/netbsd-src/commit/0abc3913ad412488a74c3360bc951= d16be034e6d >=20 > --- > aarch64/pmap: explicitly strip ARM_MMAP_* bits in pmap_phys_address() >=20 > 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. > --- >=20 > 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; > } >=20 > -#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)) >=20 > void pmap_bootstrap(vaddr_t, vaddr_t); >=20 >=20 > --- > Izumi Tsutsui >=20