Subject: Re: user mapping pci memory
To: None <cgd@cs.cmu.edu>
From: Gordon W. Ross <gwr@mc.com>
List: tech-kern
Date: 03/12/1997 14:19:39
> From: "Chris G. Demetriou" <cgd@cs.cmu.edu>
> Date: Wed, 12 Mar 1997 12:32:41 -0500
> Sender: Chris_G_Demetriou@auchentoshan.pdl.cs.cmu.edu
>
> > [ ... A potential solution to the mmap annoyances ... ]
>
> What you suggest could probably work to allow general MI exporting of
> address space, but still doesn't solve the problems of:
>
> (1) how to communicate to user-land that what's mapped really
> doesn't start at the beginning of the page,
I don't think we have any problem here to start with, because the
implementation of the mmap system call removes any page offset in
the device offset before the driver's d_map entry point gets it,
and adds that page offset back to the page-aligned address mapped
by the VM code before returning it back to user space.
> (2) transforming the physical address that the device/bus may
> present into a system bus physical address, and
I assumed the MD code would do that. See below...
> (3) sanely informing the user-land process how it's supposed
> to access the mapped region.
Mapped devices are always direct access, right?
Not sure what you mean by that question...
Here is a more specific example of what the new function might be:
/*
* Return an opaque "page identifier" suitable for return from a
* driver d_map function. The value might be a physical address,
* a page number, or something else. (Only the pmap code knows.)
* This takes care of transforming the physical address that the
* device/bus may present into a system bus physical address.
*/
vm_offset_t pmap_make_pageid
__P((bus_space_tag_t bus, vm_offset_t dev_addr));
Here is an example of how it would be used:
/*
* Return the opaque "page ID" for mapping the given combination
* of bus space and device address with the given protection, or
* return -1 for error.
*/
vm_offset_t
cg2mmap(dev, off, prot)
dev_t dev;
int off, prot;
{
struct cg2_softc *sc;
sc = cgtwo_cd.cd_devs[minor(dev)];
if (off & PGOFSET)
panic("cg2mmap");
if ((unsigned)off >= CG2_MAPPED_SIZE)
return (-1);
return (pmap_make_pageid(sc->sc_bstag, (sc->sc_phys + off)));
}