Subject: Proposal to alter VM interfaces for bus.h mmap support
To: None <tech-kern@NetBSD.ORG>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: tech-kern
Date: 09/03/1997 14:59:33
Hi folks.
As you know, one of the design considerations in the bus_dma interface
was to support mapping of DMA buffers directly into userspace. One of
the most obvious applications here is for audio devices (we currently
use a machine-dependent kludge to support mmap methods on audio devices).
Frame grabbers are another obvious application. High-speed, low-latency
message passing for massively parallel systems is yet another.
To accompany this, we also want a method of mmap'ing memory-like bus
space. A good example of this would be frame buffers. Another example
is userspace implementations of bus_space_*() methods on architectures
like the Alpha.
Unfortunately, the VM system's mmap interfaces are deficient for this.
Well, more clumsy, than anything.
Currently, a device's d_mmap entry point returns an overloaded value.
Within that value is the page frame number and some opaque information
used by some pmap's to identify the "space" in which that page frame
lives; a good example is the space identifiers used by the SPARC and
Sun 3 ports.
This makes it impossible to write machine-independent drivers that
have mmap entry points.
The bus_dmamem_mmap() (and, eventually, bus_space_mmap()) function is
provided to compute the page frame number and the opaque information
passed to the VM system.
Anyway, I'd like to clean this interface up somewhat. I'd like to
propose the following:
(1) Create a new machine-dependent VM type: vm_space_t. This
will be used only by machine-dependent code, but values
will be transported through the MI VM system. There will
be one magic value: VM_SPACE_MEMORY, which will be the
VM space value used for managed pages.
(2) Alter the interface to pmap_enter() in the following
way:
void pmap_enter_space __P((pmap_t, vm_offset_t va, vm_offset_t pa,
vm_space_t space, vm_prot_t prot, boolean_t wired));
#define pmap_enter(pmap, va, pa, prot, wired) \
pmap_enter_space((pmap), (va), (pa), VM_SPACE_MEMORY, (prot), (wired))
Also alter similar interfaces (e.g. pmap_map()) in the same
way. This eliminates the overloading of "pa" argument.
(For an example of how it's overloaded, look at the Sun 3's
pmap_enter() function.)
(3) Alter the d_mmap driver entry point interface in the following
way:
From:
int (*d_mmap) __P((dev_t dev, int off, int prot));
To:
int (*d_mmap) __P((dev_t dev, vm_offset_t off, int prot,
vm_offset_t *pap, vm_space_t *spacep));
The "int" return value is interpreted as an error code; 0
for success, an errno value otherwise. The "pap" argument
is filled in with the physical address to pass to
pmap_enter_space() (also used in the fake vm_page that is
created). The "spacep" argument is filled in, and merely
passed on by the VM system to pmap_enter_space().
With this interface change, the Sun 3 cg2 driver's mmap
routine would look like this:
int
cg2mmap(dev, off, prot, pap, spacep)
dev_t dev;
vm_offset_t off;
int prot;
vm_offset_t *pap;
vm_space_t *spacep;
{
struct cg2_softc *sc = cgtwo_cd.cd_devs[minor(dev)];
if (off & PGOFSET)
panic("cg2mmap");
if (off >= CG2_MAPPED_SIZE)
return (EINVAL);
*pap = sc->sc_phys + off;
*spacep = sc->sc_pmtype;
return (0);
}
Note, I'm using the Sun 3 because it demonstrates the
issues well. For machine-independent drivers, pap
and spacep will be filled in by bus_dmamem_mmap() and/or
bus_space_mmap().
Note that the interface to bus_dmamem_mmap() must change
to:
int bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
int nsegs, vm_offset_t off, int prot, int flags,
vm_offset_t *pap, vm_space_t *spacep));
It is expected that *spacep will always get the value
VM_SPACE_MEMORY in the bus_dmamem_mmap() case, but is
passed for consistency.
Note that this renders pmap_phys_address() obsolete.
Thoughts? I'd like to address this ASAP, since there is a project here
that is going to need this relatively soon.
Jason R. Thorpe thorpej@nas.nasa.gov
NASA Ames Research Center Home: +1 408 866 1912
NAS: M/S 258-6 Work: +1 415 604 0935
Moffett Field, CA 94035 Pager: +1 415 428 6939