Subject: /dev/[k]mem not mmap-able?
To: None <port-macppc@netbsd.org>
From: Martijn van Buul <martijnb@stack.nl>
List: port-macppc
Date: 01/23/2002 15:56:42
Hey. 

While trying to find out why the Matrox driver of XFree didn't quite
work, I strumbled across the following:

Apperently, /dev/mem isn't allowed to be mmap'ed. On other systems 
(Including other NetBSD systems), it works fine, but on NetBSD/macppc
(and probably all other PowerPC systems), it throws an EINVAL. I've studied
the kernel source a bit, and added some debug info. The mmap fails in
/sys/uvm/uvm_mmap.c, line 1212:

if(uobj==NULL)
    return ((vp->v_type == VREG) ? ENOMEM : EINVAL);

(The EINVAL is misleading, IMHO, since the manpage of mmap doesn't mention
 that EINVAL might be caused by trying to mmap a device or file which
 does not support being mmapped)

uobj can be NULL if udv_attach failed (twice, in case of a character 
device). udv_attach on its term fails because (/sys/uvm/uvm_device.c,
around line 174) (*mapfn)(device,off,accessprot) failed.

mapfn is fetched from the cdevsw[] table in /sys/arch/macppc/macppc/conf.c,
but there I may have got lost because of wicked macros ;). The cdev_mm_init()
macro in /usr/include/sys/conf.h looks sensible, and seems to support mmap.
dev_init(1,mm,mmap), which would all work out to a function mmmmap();

mmmmap() (in /usr/sys/arch/powerpc/powerpc/mem.c) returns -1 in *all* cases. 
In fact, there isn't much of a function there, expect for "return -1;"
This seems to be the case for quite a lot of platforms, and almost looks
like a stub to me.

I've written a small test program, which repeatedly tries to map 4K from
/dev/mem in an 1MB interval (up to 1GB) until it succeeds. I've tried this
on Linux, FreeBSD, NetBSD/i386 and NetBSD/sparc, and it all works. 
NetBSD/macppc doesn't. The NetBSD/sparc is a bit strange - I would have
suspected similiar behaviour (mmmmap() is broken there too), but apperently
it still works. I must confess that it was a 1.3 based machine. No, I
don't maintain it. Apperently this feature got removed.

I googled a bit, and found a reference to this on the port-bebox mailing
list, from someone doing a similiar thing. He simply said that he "fixed
that." :-/

Why is mmap() on /dev/mem broken? 

Kind regards,

Martijn.

-- 
    Martijn van Buul -  Pino@dohd.org - http://www.stack.nl/~martijnb/
	 Geek code: G--  - Visit OuterSpace: mud.stack.nl 3333
   Kees J. Bot: The sum of CPU power and user brain power is a constant.