*BSD News Article 25585


Return to BSD News archive

Newsgroups: comp.unix.bsd
Path: sserve!newshost.anu.edu.au!munnari.oz.au!constellation!osuunx.ucc.okstate.edu!moe.ksu.ksu.edu!vixen.cso.uiuc.edu!howland.reston.ans.net!cs.utexas.edu!uunet!super!rminnich
From: rminnich@super.org (Ronald G Minnich)
Subject: Re: How do I set up a 2 Meg sharable area between device driver and user?
Message-ID: <1994Jan5.033641.21494@super.org>
Sender: news@super.org (USENET News System)
Nntp-Posting-Host: descartes
Organization: Supercomputing Research Center, Bowie, MD
References: <2gc1h1$hns@senator-bedfellow.MIT.EDU> <2gd3ts$fc6@u.cc.utah.edu>
Date: Wed, 5 Jan 1994 03:36:41 GMT
Lines: 84

In article <2gd3ts$fc6@u.cc.utah.edu>,
A Wizard of Earth C <terry@cs.weber.edu> wrote:
>In article <2gc1h1$hns@senator-bedfellow.MIT.EDU> Glen Schaff <glens@space.mit.edu> writes:
>>I am working on a SUN 4.1.1 architecture, and have been trying to set up
>>a 2 meg sharable memory region, that a user program can read, and my
>>device driver writes. (finding documentation for this is about as easy as
>You will need to pin the pages, then you will need to comunicate their
>location to the driver. In all honesty, you are better of allocating
>*contiguous* wired memory in the driver itself, and then mapping it

wow, it is not this hard, we have been doing this for years. Here is 
some sample code that is typical of the breed. This is from a pseudo-device
driver I wrote that supports the TRACE option in SUNOS 4.x (they never 
shipped the driver).

This may not lint, and I don't care, it was a quick piece of work
to test something out. It has worked on sun3, sun3x, sun4, and sun4c machines
however. 

In our driver, the driver allocs trace buffers and the user can map those
buffers in. Thus walking trace records is very fast. 

Here is the kind of code that allocates the trace buffers: 
(this gets 1 page, the 0 means no sleep, there is manifest constant
 which i can never remember the name of but is probably KMEM_NOSLEEP)
(It gets contiguous pages in kernel virtual memory, they don't need to 
 be physically contiguous, and pinning only really matters if dma
  is going to happen. Is it in your case? If so, check out pageio_setup
  and bp_mapin and friends.)

	userinfo = (struct userinfo *) getpages(1,0); /* get it, no sleep */
	if (userinfo == NULL)


Here is the mmap function. Note that you can interpret offset ANY WAY YOU 
WANT. This is useful, as we use off 0 to get the the records describing 
the trace buffer, and 1 and up to get to the buffer. All you have to do 
is returning a kpfnum (kernel page frame number) to the function calling
you. TRDPRINT is a debug macro, usually off :0)


trmmap(dev, off, prot)
dev_t       dev;
off_t       off;
int         prot;
{
    register struct tr_device  *trdev;
    int         kpfnum = -1;
    int         unit = TRUNIT(dev);
    int         m = major(dev), mi = minor(dev);
    extern struct userinfo *userinfo;
    extern struct trace_rec *tracebuffer;
    extern int ntbufpages;


    TRDPRINT("trmmap:dev %d major %d minor %d off %x prot %x = req %d\n",
	    dev, m, mi, off, prot, off >> PAGESHIFT);

    if (btop(off) == 0) /* first page */
      {
	kpfnum = hat_getkpfnum(userinfo);
	TRDPRINT("kpfnum for trace stats page is 0x%x\n", kpfnum);
      }
    else
      if (btop(off) <= ntbufpages) /* data pages */
      {
	kpfnum = hat_getkpfnum((caddr_t) tracebuffer + ptob(btop(off)-1));
	TRDPRINT("kpfnum for trace data page is 0x%x\n", off);
      }
    else
      printf("off 0x%x is invalid for ntbufpages 0x%x\n", off, ntbufpages);

    return kpfnum;
}



If you need sample code to dynamically load stuff, let me know.

Now the solaris version, well :-)
ron
-- 
 rminnich@super.org      | IBM wants to run ATM at 25 mbits/sec, or 1/2 of OC-1
 (301)-805-7451 or 7312  | This would give them OC/2 for OS/2 on a PS/2