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)));
}