#!/bin/sh
# $XFree86: xc/programs/Xserver/hw/xfree86/etc/mmapSVR3.shar,v 3.3 2002/10/08 23:07:43 dawes Exp $
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 02/26/1994 03:10 UTC by root@gamma
# Source directory /home1/tmp/x11r5
#
# $XConsortium: mmapSVR3.shar /main/4 1996/02/21 17:48:01 kaleb $
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   1061 -rw-r--r-- mmap-2.2.3/CHANGELOG
#   1633 -rw-r--r-- mmap-2.2.3/COPYRIGHT
#     73 -rw-r--r-- mmap-2.2.3/DrivDesc
#   7870 -rw-r--r-- mmap-2.2.3/Makefile
#     28 -rw-r--r-- mmap-2.2.3/Master
#     75 -rw-r--r-- mmap-2.2.3/Mtune
#     25 -rw-r--r-- mmap-2.2.3/Name
#     14 -rw-r--r-- mmap-2.2.3/Node
#   3816 -rw-r--r-- mmap-2.2.3/README
#    622 -rw-r--r-- mmap-2.2.3/Space.c
#     23 -rw-r--r-- mmap-2.2.3/System
#     65 -rw-r--r-- mmap-2.2.3/description
#  12533 -rw-r--r-- mmap-2.2.3/mmap.7
#  15554 -rw-r--r-- mmap-2.2.3/mmap.c
#   1422 -rw-r--r-- mmap-2.2.3/mmap.h
#   7901 -rw-r--r-- mmap-2.2.3/mmap.man
#   1495 -rw-r--r-- mmap-2.2.3/mmaprm.1
#   3346 -rw-r--r-- mmap-2.2.3/mmaprm.c
#    843 -rw-r--r-- mmap-2.2.3/mmaprm.man
#   1453 -rw-r--r-- mmap-2.2.3/mmapstat.1
#   2531 -rw-r--r-- mmap-2.2.3/mmapstat.c
#    808 -rw-r--r-- mmap-2.2.3/mmapstat.man
#   2539 -rw-r--r-- mmap-2.2.3/tstmap.c
#
# ============= mmap-2.2.3/CHANGELOG ==============
if test ! -d 'mmap-2.2.3'; then
    echo 'x - creating directory mmap-2.2.3'
    mkdir 'mmap-2.2.3'
fi
if test -f 'mmap-2.2.3/CHANGELOG' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/CHANGELOG (File already exists)'
else
echo 'x - extracting mmap-2.2.3/CHANGELOG (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/CHANGELOG' &&
X
MMAP 2.2.3 (22 November 1993)
Workaround a problem when the page daemon (vhand) steals a mmap
region which isn't used any longer by any processes the page tables
(see mmap.c).
X
MMAP 2.2.2 (24 September 1993)
UNMAP/UNMAPRM didn't decrement the number of attached shared
memory regions after detaching. Thanks to Steve Forsythe,
<forsse@meaddata.com> for pointing to it.
X
MMAP 2.2.1 (13 September 1993)
Ioctl GETVERSION added.
X
MMAP 2.2 (12 September 1993)
New ioctl UNMAPRM added. Allows removing of regions from the
drivers list and the system. Also added a utility "mmaprm"
which does it.
X
MMAP 2.1 (8 September 1993)
Two ioctl's (GETNMMREG & GETMMREG) added to provide an interface
to a utility "mmapstat", which prints some internal information from
the MMAP driver. Some other cleanups.
X
MMAP 2.0 (7 September 1993)
Completly rewritten. The need address space is allocated by the
driver itself now.
X
MMAP 1.0 (4 August 1993)
Used kernel function mappages(). Required previous malloc() in the
calling process to allocate the needed virtuell address space.
X
SHAR_EOF
chmod 0644 mmap-2.2.3/CHANGELOG ||
echo 'restore of mmap-2.2.3/CHANGELOG failed'
Wc_c="`wc -c < 'mmap-2.2.3/CHANGELOG'`"
test 1061 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/CHANGELOG: original size 1061, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/COPYRIGHT ==============
if test -f 'mmap-2.2.3/COPYRIGHT' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/COPYRIGHT (File already exists)'
else
echo 'x - extracting mmap-2.2.3/COPYRIGHT (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/COPYRIGHT' &&
/*
X * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
X *
X * Permission to use, copy, modify, distribute, and sell this software and its
X * documentation for any purpose is hereby granted without fee, provided that
X * the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of Thomas Wolfram be used in
X * advertising or publicity pertaining to distribution of the software without
X * specific, written prior permission.  Thomas Wolfram makes no
X * representations about the suitability of this software for any purpose.
X * It is provided "as is" without express or implied warranty.
X *
X * THOMAS WOLFRAM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
X * EVENT SHALL THOMAS WOLFRAM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
X * PERFORMANCE OF THIS SOFTWARE.
X *
X * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
X *
X * SCO changes made by
X * S. Kent Hamilton <kenth@gwydion.hns.st-louis.mo.us>
X * and
X * David McCullough <davidm@stallion.oz.au>
X */
X
/* The MMAP driver is not based on any AT&T source code. It is
X * based on informations from various literature, drivers and articles
X * posted to Usenet News and by far at most on own observations, approaches
X * and a lot debugging.
X */
X
X
SHAR_EOF
chmod 0644 mmap-2.2.3/COPYRIGHT ||
echo 'restore of mmap-2.2.3/COPYRIGHT failed'
Wc_c="`wc -c < 'mmap-2.2.3/COPYRIGHT'`"
test 1633 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/COPYRIGHT: original size 1633, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/DrivDesc ==============
if test -f 'mmap-2.2.3/DrivDesc' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/DrivDesc (File already exists)'
else
echo 'x - extracting mmap-2.2.3/DrivDesc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/DrivDesc' &&
DRIVER=mmap
CLASS=io
HARDWARE=FALSE
DESCRIPTION=Memory Mapped I/O Driver
SHAR_EOF
chmod 0644 mmap-2.2.3/DrivDesc ||
echo 'restore of mmap-2.2.3/DrivDesc failed'
Wc_c="`wc -c < 'mmap-2.2.3/DrivDesc'`"
test 73 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/DrivDesc: original size 73, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/Makefile ==============
if test -f 'mmap-2.2.3/Makefile' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/Makefile (File already exists)'
else
echo 'x - extracting mmap-2.2.3/Makefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/Makefile' &&
#/*
# * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
# *
# * Permission to use, copy, modify, distribute, and sell this software and its
# * documentation for any purpose is hereby granted without fee, provided that
# * the above copyright notice appear in all copies and that both that
# * copyright notice and this permission notice appear in supporting
# * documentation, and that the name of Thomas Wolfram be used in
# * advertising or publicity pertaining to distribution of the software without
# * specific, written prior permission.  Thomas Wolfram makes no
# * representations about the suitability of this software for any purpose.
# * It is provided "as is" without express or implied warranty.
# *
# * THOMAS WOLFRAM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
# * EVENT SHALL THOMAS WOLFRAM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
# * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# * PERFORMANCE OF THIS SOFTWARE.
# *
# * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
# */
X
X     SHELL = /bin/sh
X
####################################################################
# For ISC x.x.x uncomment the following
X     OSDEF = -DISC		# Currently not used in the code
#
# ISC's install
X   INSTALL = /etc/install -i -n $(BINDIR) -u
#
####################################################################
# For SCO Unix 3.2v2.x and 3.2v4.x uncomment the following
#     OSDEF = -DSCO
#
# If you have GNU fileutils use this one.
#   INSTALL = /usr/local/bin/install -o
#
# If not and you have X installed try this.
#   INSTALL = /usr/X386/bin/bsdinst -o
# No to that one?  <sigh> (Get GNU fileutils!)  Install mmapstat
# and mmaprm by hand...  sorry.
#
####################################################################
X
# If you don't want the new tunable parameter 'NMMAPREG' be added to
# /etc/conf/cf.d/mtune, comment this out.
ADDTUNABLE = addtunable
X
# Directory where mmapstat and mmaprm will go
X    BINDIR = /usr/local/bin
# and where you want the manual pages to go.
X CATMANDIR = /usr/local/catman/p_man
X
# Do you want compressed manual pages? If not, uncomment 'true'.
#  COMPRESS = true
#  COMPRESS = compress
#  COMPRESS = pack
X  COMPRESS = gzip --suffix .z
X
# It's not tested with gcc, you should use the system's native C compiler.
X        CC = cc
# Link utilities with shared C library.
X      LIBS = -lc_s
X
####################################################################
# Normally you need not change anything below...
X
X   DCFLAGS = -O -DINKERNEL $(LKDEFINES) $(OSDEF) #-DDEBUG
X    CFLAGS = -O $(OSDEF)
X LKDEFINES = `test -r /etc/conf/cf.d/defines && cat /etc/conf/cf.d/defines; exit 0`
X
X  CONFNAME = mmap
X  DRVRNAME = Driver.o
MY1TUNABLE = NMMAPREG
X
X   INCLSYS = /usr/include/sys
X  LKBINDIR = /etc/conf/bin
X   LKCFDIR = /etc/conf/cf.d
LKSCONFDIR = /etc/conf/sdevice.d
LKNCONFDIR = /etc/conf/node.d
LKDRVRDIR  = /etc/conf/pack.d/mmap
X
# ISC specific
LKKCONFDIR = /etc/conf/kconfig.d
X   ISC30KC = /etc/KC
X
X
all: Driver.o mmapstat mmaprm tstmap
X
$(INCLSYS)/mmap.h: mmap.h
X	cp mmap.h $(INCLSYS)/mmap.h
X
Driver.o: mmap.c $(INCLSYS)/mmap.h Makefile
X	$(CC) -c $(DCFLAGS) mmap.c
X	mv mmap.o Driver.o
X
mmapstat: mmapstat.c $(INCLSYS)/mmap.h Makefile
X	$(CC) $(CFLAGS) -o mmapstat mmapstat.c $(LIBS)
X
mmaprm: mmaprm.c $(INCLSYS)/mmap.h Makefile
X	$(CC) $(CFLAGS) -o mmaprm mmaprm.c $(LIBS)
X
tstmap: tstmap.c $(INCLSYS)/mmap.h Makefile
X	$(CC) $(CFLAGS) -o tstmap tstmap.c $(LIBS)
X
install:
X	@echo Type:
X	@echo "     make install.isc2.0         For installing on ISC 2.0"
X	@echo "     make install.isc2.2         For installing on ISC 2.2"
X	@echo "     make install.isc3.0         For installing on ISC 3.0"
X	@echo "     make install.isc4.0         For installing on ISC 4.0"
X	@echo "     make install.sco322         For installing on SCO 3.2v2"
X	@echo "     make install.sco324         For installing on SCO 3.2v4"
X	@echo ""
X
X
install.isc2.0:	Driver.o Space.c System Master Node Name # $(ADDTUNABLE) install.utils description
X	@echo Installing device driver files in /etc/conf...
X	@if [ ! -d $(LKDRVRDIR) ] ; then echo It\'s a new installation... ; \
$(LKBINDIR)/idinstall -k -a $(CONFNAME) ; else \
echo It\'s an update installation... ; $(LKBINDIR)/idinstall -k -u $(CONFNAME) \
X ; fi
X	@echo Updating $(LKKCONFDIR)/description...
X	@grep $(CONFNAME) $(LKKCONFDIR)/description >/dev/null || cat description >> $(LKKCONFDIR)/description
X	@echo DONE.
X
install.isc2.2:	install.isc2.0
X
install.isc3.0:	Driver.o Space.c System Master Node DrivDesc $(ADDTUNABLE) install.utils
X	@echo Installing device driver files in /etc/conf...
X	@if [ ! -d $(LKDRVRDIR) ] ; then echo It\'s a new installation... ; \
$(LKBINDIR)/idinstall -k -a $(CONFNAME) ; else \
echo It\'s an update installation... ; $(LKBINDIR)/idinstall -k -u $(CONFNAME) \
X ; fi
X	@cp DrivDesc $(LKDRVRDIR)/DrivDesc
X	@chmod 644 $(LKDRVRDIR)/DrivDesc
X	@echo DONE.
X	
install.isc4.0: install.isc3.0
X	$(_NULL_)
X
install.sco324:	Driver.o Space.c System Master Node Name $(ADDTUNABLE) install.utils
X	@echo Installing device driver files in /etc/conf...
X	@if [ ! -d $(LKDRVRDIR) ] ; then echo It\'s a new installation... ; \
$(LKBINDIR)/idinstall -k -a $(CONFNAME) ; else \
echo It\'s an update installation... ; $(LKBINDIR)/idinstall -k -u $(CONFNAME) \
X ; fi
X
install.sco322: install.sco324
X
# add tunable NMMAPREG to mtune
addtunable: Mtune
X	@echo Updating $(LKCFDIR)/mtune...
X	@grep $(MY1TUNABLE) $(LKCFDIR)/mtune >/dev/null || cat Mtune >> $(LKCFDIR)/mtune
X	@if [ -f $(ISC30KC)/DEVICE -a -f $(ISC30KC)/ALL ]; then \
echo Updating $(ISC30KC)/DEVICE for kconfig...; \
grep $(MY1TUNABLE) $(ISC30KC)/DEVICE >/dev/null || \
(if [ -f $(ISC30KC)/DEVICE ] ; \
X then mv $(ISC30KC)/DEVICE $(ISC30KC)/DEVICE.Orig; \
X (sed -e '/^$$/d' $(ISC30KC)/DEVICE.Orig; echo $(MY1TUNABLE)) \
X   >$(ISC30KC)/DEVICE; \
X fi) ; \
echo Updating $(ISC30KC)/ALL for kconfig...; \
grep $(MY1TUNABLE) $(ISC30KC)/ALL >/dev/null || \
(if [ -f $(ISC30KC)/ALL ] ; then mv $(ISC30KC)/ALL $(ISC30KC)/ALL.Orig; \
X (sed -e '/^$$/d' $(ISC30KC)/ALL.Orig; echo $(MY1TUNABLE)) >$(ISC30KC)/ALL; \
fi) ; \
X	fi
X
X
# mmapstat must be setuid root, mmaprm should only executable for superuser
install.utils: mmapstat mmaprm
X	$(INSTALL) root -g bin -m 4755 mmapstat $(BINDIR)
X	strip $(BINDIR)/mmapstat
X	mcs -d $(BINDIR)/mmapstat
X	$(INSTALL) root -g sys -m 4750 mmaprm $(BINDIR)
X	strip $(BINDIR)/mmaprm
X	mcs -d $(BINDIR)/mmaprm
X
install.catman:
X	-mkdir $(CATMANDIR)/man7
X	-mkdir $(CATMANDIR)/man1
X	-rm $(CATMANDIR)/man7/$(CONFNAME).7*
X	nroff -man $(CONFNAME).man >$(CATMANDIR)/man7/$(CONFNAME).7
X	$(COMPRESS) $(CATMANDIR)/man7/$(CONFNAME).7
X	-rm $(CATMANDIR)/man1/mmapstat.1*
X	nroff -man mmapstat.man >$(CATMANDIR)/man1/mmapstat.1
X	$(COMPRESS) $(CATMANDIR)/man1/mmapstat.1
X	-rm $(CATMANDIR)/man1/mmaprm.1*
X	nroff -man mmaprm.man >$(CATMANDIR)/man1/mmaprm.1
X	$(COMPRESS) $(CATMANDIR)/man1/mmaprm.1
X
install.form-catman:
X	-mkdir $(CATMANDIR)/man7
X	-mkdir $(CATMANDIR)/man1
X	-rm $(CATMANDIR)/man7/$(CONFNAME).7*
X	cp $(CONFNAME).7 $(CATMANDIR)/man7/$(CONFNAME).7
X	chmod 644 $(CATMANDIR)/man7/$(CONFNAME).7
X	$(COMPRESS) $(CATMANDIR)/man7/$(CONFNAME).7
X	-rm $(CATMANDIR)/man1/mmapstat.1*
X	cp mmapstat.1 $(CATMANDIR)/man1/mmapstat.1
X	chmod 644 $(CATMANDIR)/man1/mmapstat.1
X	$(COMPRESS) $(CATMANDIR)/man1/mmapstat.1
X	-rm $(CATMANDIR)/man1/mmaprm.1*
X	cp mmaprm.1 $(CATMANDIR)/man1/mmaprm.1
X	chmod 644 $(CATMANDIR)/man1/mmaprm.1
X	$(COMPRESS) $(CATMANDIR)/man1/mmaprm.1
X
fman: mmap.man mmapstat.man mmaprm.man
X	nroff -man mmap.man >mmap.7
X	nroff -man mmapstat.man >mmapstat.1
X	nroff -man mmaprm.man >mmaprm.1
X
clean:
X	rm -f Driver.o mmapstat mmaprm tstmap core
X
clobber: clean
X
SHAR_EOF
chmod 0644 mmap-2.2.3/Makefile ||
echo 'restore of mmap-2.2.3/Makefile failed'
Wc_c="`wc -c < 'mmap-2.2.3/Makefile'`"
test 7870 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/Makefile: original size 7870, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/Master ==============
if test -f 'mmap-2.2.3/Master' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/Master (File already exists)'
else
echo 'x - extracting mmap-2.2.3/Master (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/Master' &&
mmap	Ii	ic		mmap	0	0	1	1	-1
SHAR_EOF
chmod 0644 mmap-2.2.3/Master ||
echo 'restore of mmap-2.2.3/Master failed'
Wc_c="`wc -c < 'mmap-2.2.3/Master'`"
test 28 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/Master: original size 28, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/Mtune ==============
if test -f 'mmap-2.2.3/Mtune' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/Mtune (File already exists)'
else
echo 'x - extracting mmap-2.2.3/Mtune (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/Mtune' &&
* Memory Mapped I/O Parameters ------
NMMAPREG        64      8       1024
SHAR_EOF
chmod 0644 mmap-2.2.3/Mtune ||
echo 'restore of mmap-2.2.3/Mtune failed'
Wc_c="`wc -c < 'mmap-2.2.3/Mtune'`"
test 75 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/Mtune: original size 75, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/Name ==============
if test -f 'mmap-2.2.3/Name' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/Name (File already exists)'
else
echo 'x - extracting mmap-2.2.3/Name (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/Name' &&
Memory Mapped I/O Driver
SHAR_EOF
chmod 0644 mmap-2.2.3/Name ||
echo 'restore of mmap-2.2.3/Name failed'
Wc_c="`wc -c < 'mmap-2.2.3/Name'`"
test 25 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/Name: original size 25, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/Node ==============
if test -f 'mmap-2.2.3/Node' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/Node (File already exists)'
else
echo 'x - extracting mmap-2.2.3/Node (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/Node' &&
mmap	mmap c	0
SHAR_EOF
chmod 0644 mmap-2.2.3/Node ||
echo 'restore of mmap-2.2.3/Node failed'
Wc_c="`wc -c < 'mmap-2.2.3/Node'`"
test 14 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/Node: original size 14, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/README ==============
if test -f 'mmap-2.2.3/README' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/README (File already exists)'
else
echo 'x - extracting mmap-2.2.3/README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/README' &&
X
MMAP - Memory Mapped I/O Driver v2.2.3
Installation
------------------------------------------------------------------------
MMAP is a pseudo device driver which provides memory mapped I/O for user
processes, i.e. direct mapping of physical memory ranges into the user's
virtual address space for fast access. It is especially useful for accessing
the linear frame buffers of certain graphics hardware from the user level.
X
Note, the driver is currently tested only under ISC 2.0.2, ISC 2.2.1, 
ISC 3.0 and ISC 4.0 although it should work on any SVR3.2 based system.
It should also work on SCO, but page locking is not tested yet with SCO
and for this reason disabled for SCO. (look into mmap.c). But if mapping of
ranges less or equal 4MB is enough for your needs it could be easier to use
the "dmmap" driver by David McCullough <davidm@stallion.oz.au> which uses
the vas*() functions already provided by the SCO kernel.
A description of the driver itself and how to use it you'll find in the
accompanied manual page.
X
0. Login as root.
X
1. Unpack the archive with:
X
X	# gzcat mmap-2.2.3.t.z | tar xovf -
X
2. Edit the Makefile for your system. Change BINDIR, CATMANDIR, COMPRESS
X   if you like.
X   Comment out ADDTUNABLE if you don't want the new tunable system
X   parameter NMMAPREG be added to /etc/conf/cf.d/mtune.
X
3. Compile the driver, the mmapstat, mmaprm and tstmap utilities:
X
X	# make
X
3. Install the driver, the mmapstat and mmaprm utilities:
X
X	# make install.<system>
X
X   Where <system> is currently only isc3.0, isc4.0, sco322 or sco324.
X   A list on which system the installation procedure is supported
X   you can get with:
X
X	# make install
X
X   The driver adds a new tunable system parameter "NMMAPREG" in
X   /etc/conf/cf.d/mtune (if you didn't disable it in the Makefile
X   before). For the ISC 3.0/4.0 systems also files in /etc/KC are
X   updated to provide access to NMMAPREG in the ISC 3.0/4.0 style
X   kconfig tool as well as a ISC 3.0/4.0 style "DrivDesc" file is
X   provided too.
X
4. If you are on ISC, run kconfig. Adjust the new system tunable
X   parameter NMMAPREG if you think it is needed. You can also adjust
X   SHMSEG if you like. See the new manual page mmap(7L) for their meaning.
X
X   If you are on SCO or another SVR3.2, you can adjust NMMAPREG to
X   (e.g.) 128, with:
X
X	# /etc/conf/bin/idtune  NMMAPREG  128
X
X   (BTW, this would also work for ISC.)
X
X   If you didn't add the tunable parameter NMMAPREG to the system but
X   you want to change it, you must edit /etc/conf/pack.d/mmap/space.c
X   or /usr/include/sys/mmap.h.
X
5. Build a new kernel and install it.
X
5. Run the test program:
X
X	# tstmap
X
X   It maps the main bios in the process' address space. If you have
X   e.g. a AMI bios you will see a string like:
X
X   0123AAAAMMMMIIII05/05/91(C)1990 American Megatrends Inc., All Rights
X   Reserved
X
X   After unmapping the program should dump core when it wants to access
X   the previous mapped range again.  
X
X   Under ISC you can check the output of the tstmap, e.g. with:
X
X	# hd -s 0xF0000 /dev/mem | more
X
X
6. Run the mmapstat utility hereafter, which should give following output:
X
X	# mmapstat
X	Currently memory mapped I/O regions as of Wed Sep  8 17:51:48 1993
X	#      Physical Address     Size      Reference Count
X	0      0x000F0000            64k                    0
X
7. Installing the manual pages for mmap(7L), mmapstat(1L), mmaprm(1L) if you
X   like.
X   If you have nroff type (for getting SVR3 style "cat"man pages)
X
X	# make install.catman
X
X   If you don't have nroff, you can use the accompanied pre-formatted
X   man pages, type:
X
X	# make install.form-catman
X
If you have any bug reports, questions or hints then you can send them to:
X
Thomas Wolfram
wolf@prz.tu-berlin.de or thomas@aeon.in-berlin.de
X
SHAR_EOF
chmod 0644 mmap-2.2.3/README ||
echo 'restore of mmap-2.2.3/README failed'
Wc_c="`wc -c < 'mmap-2.2.3/README'`"
test 3816 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/README: original size 3816, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/Space.c ==============
if test -f 'mmap-2.2.3/Space.c' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/Space.c (File already exists)'
else
echo 'x - extracting mmap-2.2.3/Space.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/Space.c' &&
X
/* Configuration file for the MMAP driver
X *
X * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
X * 
X * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
X */
X
#if !defined (M_I286)
#ident	"@(#)space.c - MMAP v2.2.3, Copyright (c) Thomas Wolfram 1993"
#endif
X
#include "sys/types.h"
#include "sys/sysmacros.h"
#include "sys/immu.h"
#include "sys/region.h"
X
#include "sys/mmap.h"
X
#include "config.h"		/* to get tunable parameter NMMAPREG */
X
X
/* I/O regions memory mapped by the driver
X */
mmapreg_t mmapreg[NMMAPREG];
X
/* size of this array for use by the driver
X */
uint nmmapreg = NMMAPREG;
SHAR_EOF
chmod 0644 mmap-2.2.3/Space.c ||
echo 'restore of mmap-2.2.3/Space.c failed'
Wc_c="`wc -c < 'mmap-2.2.3/Space.c'`"
test 622 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/Space.c: original size 622, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/System ==============
if test -f 'mmap-2.2.3/System' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/System (File already exists)'
else
echo 'x - extracting mmap-2.2.3/System (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/System' &&
mmap	Y	1	0	0	0	0	0	0	0
SHAR_EOF
chmod 0644 mmap-2.2.3/System ||
echo 'restore of mmap-2.2.3/System failed'
Wc_c="`wc -c < 'mmap-2.2.3/System'`"
test 23 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/System: original size 23, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/description ==============
if test -f 'mmap-2.2.3/description' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/description (File already exists)'
else
echo 'x - extracting mmap-2.2.3/description (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/description' &&
mmap    -    -     io     -             Memory Mapped I/O Driver
SHAR_EOF
chmod 0644 mmap-2.2.3/description ||
echo 'restore of mmap-2.2.3/description failed'
Wc_c="`wc -c < 'mmap-2.2.3/description'`"
test 65 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/description: original size 65, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/mmap.7 ==============
if test -f 'mmap-2.2.3/mmap.7' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/mmap.7 (File already exists)'
else
echo 'x - extracting mmap-2.2.3/mmap.7 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmap.7' &&
X
X
X
X          mmap(7L)                     386/ix                      mmap(7L)
X
X
X
X          NAME
X               mmap - MMAP ioctl commands (memory mapped I/O support)
X
X          SYNOPSIS
X               #include <sys/types.h>
X               #ifndef SCO
X               #include <sys/at_ansi.h>
X               #include <sys/kd.h>
X               #else
X               #include <sys/vtkd.h>
X               #endif
X               #include <sys/sysmacros.h>
X               #include <sys/immu.h>
X               #include <sys/region.h>
X               #include <sys/mmap.h>
X
X               int ioctl(fildes, command, arg);
X               int fildes, command;
X
X          DESCRIPTION
X               MMAP is a pseudo device driver which provides memory mapped
X               I/O for user processes, i.e. direct mapping of physical
X               memory ranges into the user's virtual address space for fast
X               access. It is especially useful for accessing the linear
X               frame buffers of certain graphic hardware from the user
X               level.
X
X               To executing the MMAP ioctl commands fildes must be an open
X               file descriptor [see open(2)] that refers to the special
X               character device /dev/mmap. The effective user ID of the
X               calling process must be superuser.
X               The driver uses shared memory type regions for mapping. So
X               the maximum number of regions the driver can attach to a
X               process is limited by the maximum number of shared memory
X               regions which can be attached to the process [see shmget(2),
X               shmop(2), shmctl(2)]. This number is a tunable system param-
X               eter (SHMSEG) [see kconfig(1), idtune(1M)].
X               The number of regions which the driver is able to map
X               system-wide (i.e. to all running processes) is limited too.
X               This number is also a tunable system parameter (NMMAPREG).
X
X               Note, the MMAP driver grows the virtual address space of the
X               calling process by itself. Allocating address space before
X               with malloc(3) isn't necessary and will not work.
X               The mapping regions allocated by the driver will always be
X               sharable, never private to a process. Regions can be of type
X               read/write or read/only.  This depends from the mode
X               /dev/mmap is opened [see open(2)].  Once a region is allo-
X               cated and mapped to a process it will normally remain in the
X               system (until reboot) even if the last process which pointed
X               at it detaches it from its address space. (This is not much
X               waste since the MMAP driver allocates no physical pages for
X               the mapping region.)  But with the UNMAPRM ioctl removing
X
X
X          Rev. 2.2.3, 22 November 1993                               Page 1
X
X
X
X
X
X
X          mmap(7L)                     386/ix                      mmap(7L)
X
X
X
X               after unmapping can be requested [see below and mmaprm(1L)].
X               If a process wants to map in the same memory range like
X               another one (e.g. if it's the same program which is running
X               again) it will be attached with the already existing region
X               by the driver. Same applies if the processes which requests
X               the same mapping are running simultaneously.
X
X             Ioctl Calls
X               The following ioctl commands can be used:
X
X               MAP
X                 This call maps physical memory into the virtual address
X                 space of the user process. The following structure,
X                 defined in <sys/kd.h> [see display(7)], is pointed to by
X                 the argument arg to the ioctl:
X
X                 struct kd_memloc {
X                      char  *vaddr;     /* virtual address to map to */
X                      char  *physaddr;  /* physical address to map from */
X                      long  length;     /* size in bytes to map */
X                      long  ioflg;      /* not used by the MMAP driver */
X                 };
X
X                 The vaddr argument is the linear address in the process
X                 where the physical memory range will appear. This address
X                 must be on a boundary specified by the machine dependant
X                 constant MMAPLBA, defined in <sys/mmap.h>. If vaddr is
X                 equal to zero the address is selected by the driver
X                 itself.
X                 The physaddr argument is the physical address of the
X                 memory range that will be mapped in. It must be on a page
X                 boundary.
X                 The length argument is the size of the memory range that
X                 will be mapped in. It will be rounded up to a multiple of
X                 the size of a page by the driver.
X                 On success the ioctl will return the virtual address where
X                 the memory is mapped in. It will fail if one or more of
X                 the following is true:
X
X                   [EPERM]        The effective user ID of the calling pro-
X                                  cess is not superuser.
X
X                   [EFAULT]       The user address pointed to by arg is
X                                  illegal.
X
X                   [EINVAL]       The vaddr argument is not equal to zero,
X                                  and the value is an illegal address (not
X                                  on a MMAPLBA boundary, already used in
X                                  the process or not below MAXUVADR, as
X                                  defined in <sys/immu.h>).
X
X                   [EINVAL]       The physaddr argument is not on a page
X                                  boundary.
X
X
X          Rev. 2.2.3, 22 November 1993                               Page 2
X
X
X
X
X
X
X          mmap(7L)                     386/ix                      mmap(7L)
X
X
X
X                   [ENOMEM]       The vaddr argument is equal to zero and
X                                  the driver is not able to find a proper
X                                  region in the user's address space where
X                                  the memory range would fit in.
X
X                   [ENOMEM]       The size of the user's virtual address
X                                  space would exceed the system-imposed
X                                  limit.
X
X                   [ENOMEM]       Not enough system internal space avail-
X                                  able to grow the user's virtual address
X                                  space.
X
X                   [EMFILE]       The number of shared memory segments
X                                  attached to the calling process would
X                                  exceed the system-imposed limit.
X
X                   [EMFILE]       The number of all memory mapped regions
X                                  in the system would exceed the driver-
X                                  imposed limit.
X
X               UNMAP
X                 This call unmaps previously mapped physical memory from
X                 the calling process.  The argument arg to the ioctl must
X                 be the virtual address as returned by the previous MAP
X                 ioctl.
X                 It will fail if one or more of the following is true:
X
X                   [EPERM]        The effective user ID of the calling pro-
X                                  cess is not superuser.
X
X                   [EINVAL]       If arg is not the start address of a
X                                  region mapped by the driver to the cal-
X                                  ling process.
X
X               UNMAPRM
X                 Same like UNMAP but removes the concerning region from the
X                 systems internal list, if no other process is still using
X                 it [see mmaprm(1L)].
X
X               GETNMMREG
X                 This call returns the number of the memory mapped I/O
X                 regions which exists currently in the system [see
X                 mmapstat(1L)]. It requires no argument. It will fail if
X                 one or more of the following is true:
X
X                   [EPERM]        The effective user ID of the calling pro-
X                                  cess is not superuser.
X
X               GETMMREG
X                 This call returns the current status of the MMAP driver.
X                 The argument arg must be a pointer to an array of elements
X                 of the following type (defined in <sys/mmap.h>):
X
X
X          Rev. 2.2.3, 22 November 1993                               Page 3
X
X
X
X
X
X
X          mmap(7L)                     386/ix                      mmap(7L)
X
X
X
X                 typedef struct mmapinfo {
X                      paddr_t physaddr; /* physical address */
X                      long  length;     /* size in bytes */
X                      short refcnt;     /* number of users */
X                      /* pointing currently at this region */
X                 } mmapinfo_t;
X
X                 which is filled by the driver for every region currently
X                 exists.  The array must have as much elements as the
X                 number returned by the GETNMMREG ioctl states [see
X                 mmapstat(1L)].  The command will fail if one or more of
X                 the following is true:
X
X                   [EPERM]        The effective user ID of the calling pro-
X                                  cess is not superuser.
X
X                   [EFAULT]       The user address pointed to by arg is
X                                  illegal.
X
X
X
X               GETVERSION
X                 Returns version number of driver, e.g. version 2.2.1 would
X                 be returned as 0x0221.
X
X          FILES
X               /dev/mmap
X                 Character device interface to the driver.
X
X          SEE ALSO
X               open(2), ioctl(2), display(7), shmget(2), shmop(2),
X               shmctl(2), kconfig(1), idtune(1M), intro(2), mmapstat(1L),
X               mmaprm(1L).
X
X          DIAGNOSTICS
X               Upon sucessful completion, the return value is as follows:
X
X                    The MAP ioctl returns the user's address where the phy-
X                    sical memory is mapped in.
X
X                    The UNMAP and UNMAPRM ioctl's return a value of 0.
X
X                    The GETNMMREG ioctl returns the number of memory mapped
X                    I/O regions which exists currently in the system.
X
X                    The GETMMREG ioctl returns a value of 0.
X
X                    The GETVERSION ioctl returns the version number.
X
X               Otherwise, a value of -1 is returned, and errno [see
X               intro(2)] is set to indicate the error.
X
X          BUGS
X
X
X          Rev. 2.2.3, 22 November 1993                               Page 4
X
X
X
X
X
X
X          mmap(7L)                     386/ix                      mmap(7L)
X
X
X
X               Please report bugs to:  wolf@prz.tu-berlin.de or
X               thomas@aeon.in-berlin.de.
X
X          COPYING
X               Copyright (c) 1993 Thomas Wolfram
X
X          AUTHOR
X               Thomas Wolfram
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X          Rev. 2.2.3, 22 November 1993                               Page 5
X
X
X
SHAR_EOF
chmod 0644 mmap-2.2.3/mmap.7 ||
echo 'restore of mmap-2.2.3/mmap.7 failed'
Wc_c="`wc -c < 'mmap-2.2.3/mmap.7'`"
test 12533 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/mmap.7: original size 12533, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/mmap.c ==============
if test -f 'mmap-2.2.3/mmap.c' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/mmap.c (File already exists)'
else
echo 'x - extracting mmap-2.2.3/mmap.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmap.c' &&
/*
X * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
X *
X * Permission to use, copy, modify, distribute, and sell this software and its
X * documentation for any purpose is hereby granted without fee, provided that
X * the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of Thomas Wolfram be used in
X * advertising or publicity pertaining to distribution of the software without
X * specific, written prior permission.  Thomas Wolfram makes no
X * representations about the suitability of this software for any purpose.
X * It is provided "as is" without express or implied warranty.
X *
X * THOMAS WOLFRAM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
X * EVENT SHALL THOMAS WOLFRAM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
X * PERFORMANCE OF THIS SOFTWARE.
X *
X * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
X */
X
#if !defined (M_I286)
#ident	"@(#)mmap.c - MMAP v2.2.3, Copyright (c) Thomas Wolfram 1993"
#endif
X
#define MMAP_MAJ 2
#define MMAP_MIN 2
#define MMAP_PL  3
#define MMAPVERSION MMAP_MAJ*256 + MMAP_MIN*16 + MMAP_PL
X
#include <sys/types.h>
#include <sys/file.h>
#include <sys/param.h>
#include <sys/dir.h>
#include <sys/signal.h>
#include <sys/user.h>
X
#include <sys/errno.h>
X
#ifndef SCO
#include <sys/at_ansi.h>	/* get typedef needed in kd.h	*/
#include <sys/kd.h>		/* get struct kd_memloc		*/
#else
#include <sys/vtkd.h>
#endif
X
#include <sys/sysmacros.h>
#include <sys/immu.h>
#include <sys/region.h>
#include <sys/proc.h>
X
#include <sys/ipc.h>		/* get typedef needed in shm.h	*/
#include <sys/shm.h>		/* get shminfo			*/
X
#include <sys/mmap.h>
X
/* For SCO, page locking is done not per-page table entry, but
X * per-pfdat.
X */
#ifndef PG_LOCK
#define PG_LOCK 0
#endif
X
#define False 0
#define True  1
X
/* Move address x to previous and next low boundary address.
X */
#define prev_ba(x) (caddr_t)((uint)x & ~(MMAPLBA-1))
#define next_ba(x) (caddr_t)(((uint)x + MMAPLBA) & ~(MMAPLBA-1))
X
/* Nowhere else declared. */
extern dbd_t *finddbd();
X
/* System's shared memory info structure.
X */
extern struct shminfo shminfo;
X
/* Physical addresses of I/O regions memory mapped by the driver.
X * Defined in space.c.
X */
extern mmapreg_t mmapreg[];
X
/* Size of this array for use by the driver. Defined in space.c.
X */
extern uint nmmapreg;
X
int mmapinit();
int mmapioctl();
X
static caddr_t FindVirtAddr();
X
X
/* Number of I/O regions memory mapped currently by the driver. */
static map_cnt	= 0;
X
static struct kd_memloc memDesc;
static mmapinfo_t ibuf;
X
X
int mmapinit()
{
X    printf("Memory Mapped I/O Driver v%d.%d.%d installed.\n",
X	   MMAP_MAJ, MMAP_MIN, MMAP_PL);
X    printf("Copyright (c) 1993 Thomas Wolfram\n\n");
X
}
X
int mmapioctl(dev, cmd, arg, mode)
X    int dev;
X    int cmd;
X    int arg;
X    int mode;
{
X    /* Don't put this much variables at the kernel stack. Although it
X     * wouldn't matter, probably...
X     */
X    static reg_t  	  *Reg_p;
X    static preg_t 	  *PReg_p;
X    static pde_t	  *pte;		/* page table entry		*/
X    static dbd_t	  *dbdte;	/* disk block descriptor entry	*/
X    static unsigned char   accmode;
X    static int	   	   FreeReg;
X    register uint	   i, off;
X    register paddr_t	   pmem;
X
X    
X    /* Only superuser is allowed to do that. U.u_error is set to
X     * EPERM if not superuser.
X     */
X    if(!suser())
X	return;
X
X    /* Default for unmapping is don't freeing the region */
X    FreeReg = False;
X
X    switch(cmd) {
X
X	/* Map physical memory into process address space.
X         */
X	case MAP:
X
X	    /* Get the memory description block from user space.
X	     */
X	    if(copyin((caddr_t)arg, &memDesc, sizeof(memDesc)) == -1) {
X		u.u_error = EFAULT;
X		break;
X	    }
X
X	    /* Physical address must be page aligned.
X	     */
X	    if(poff(memDesc.physaddr) != 0) {
X		u.u_error = EINVAL;
X		break;
X	    }
X
X	    /* Check whether we already reached the limit of
X	     * attachable shared memory regions of this process.
X	     */
X	    if(!(u.u_nshmseg < shminfo.shmseg)) {
X		u.u_error = EMFILE;
X		break;
X	    }
X
X	    /* If no mapping address given by the user try to find one.
X	     */
X	    if(memDesc.vaddr == (caddr_t)0) {
X		if((memDesc.vaddr = FindVirtAddr(memDesc.length)) == NULL) {
X		    u.u_error = ENOMEM;
X		    break;
X		}
X	    }
X
X	    /* Check whether this physical range is already mapped to
X	     * a region. If so use it and don't allocate a new region.
X	     */
X	    Reg_p = NULL;
X	    for(i = 0; i < map_cnt; i++) {
X		if((paddr_t)memDesc.physaddr == mmapreg[i].physaddr &&
X		       btoc(memDesc.length)  == mmapreg[i].Reg_p->r_pgsz) {
X			Reg_p = mmapreg[i].Reg_p;
X			break;
X		}
X	    }
X
X
X	    if(Reg_p != NULL) {
X
X		/* If we have still such a region lock it.
X		 */
X		reglock(Reg_p);
X
X		/* XXXX This is a ugly hack.
X		 * If our region isn't any longer referenced by a process
X		 * it's possible that vhand steals the page tables of our
X		 * region. Attaching such a region with swapped-out page
X		 * tables doesn't work, because the page directory entries
X		 * of the process get a present-bit set to 1 and valid re-
X		 * ferences to page tables but which contain entries of in-
X		 * valid non-present pages. And the related dbd tables still
X		 * contain the type DBD_IOMAP.
X		 * I.e. the effect is there won't occur a page fault to
X		 * read the swapped-out page tables in, as I expected. The
X		 * page fault will instead occur in the second level (i.e. in
X		 * the page tables) when attempting to read the non-present
X		 * pages from disk or elsewhere. The kernel will look in the
X		 * dbd table and find the type DBD_IOMAP, but which is invalid
X		 * for a non-present page. Hence it would panic then with:
X		 * "vfault - bad dbd_type".
X		 *
X		 * Also I have no idea how I could the swapped-out page tables
X		 * read in "by hand". The "pseudo page directory" of the re-
X		 * gion (addressed by Reg_p->r_list) contains obviously only
X		 * the base addresses and not the page state flags. Also
X		 * I don't know how to find the dbd's of the page table's
X		 * pages.
X		 * 
X		 * Probably I did something wrong here. If you've an idea
X		 * please let me know. Thanks.
X		 *
X		 * Anyway, until then I simply throw away the region if
X		 * the page tables of it are swapped out and then I reallocate
X		 * the same region.
X		 */
X		if(Reg_p->r_flags & RG_SWAP) {
X
X		    /* Freereg takes only effect if no users pointing
X		     * at it.
X		     */
X		    if(Reg_p->r_refcnt == 0) {
X			Reg_p->r_flags &= ~RG_NOFREE;
X			freereg(Reg_p);
X
X			/* Free the old slot and force allocating a
X			 * new region.
X			 */
X			for(i = i; i < map_cnt; i++)
X				mmapreg[i] = mmapreg[i+1];
X			map_cnt--;
X
X			Reg_p = NULL;
X
#ifdef DEBUG
X			printf("MMAP: Info - reallocate region [a=0x%x, l=%dk]\n", memDesc.physaddr, memDesc.length/1024);
#endif
X		    }
X		    else {
X			/* I hope this point here will never be reached!
X			 * Or - better - page tables are read in correctly
X			 * by the system. So we don't panic in the hope
X			 * it works.
X			 */
X			printf("MMAP: Warning - region [a=%x, l=%dk] still used but page tables are swapped out!\n", memDesc.physaddr, memDesc.length/1024);
X			printf("MMAP: Cannot reallocate this region!\n");
X			printf("MMAP: Please email Thomas Wolfram <thomas@aeon.in-berlin.de> or\n      <wolf@prz.tu-berlin.de>. Thanks.\n");
X
X			/* panic("MMAP: PANIC\n");
X			 */
X		    }
X		}
X	    }
X
X
X	    /* If necessary allocate a new region, type is shared memory.
X	     */
X	    if(Reg_p == NULL) {
X
X		/* Check whether we are at the limit of regions we can map.
X		 */
X		if(map_cnt > nmmapreg) {
X		    u.u_error = EMFILE;
X		    break;
X		}
X
X		/* Allocate new region which will be locked.
X		 */
X	    	if((Reg_p = allocreg(NULL, RT_SHMEM, 0)) == NULL)
X		    break;
X	    }
X
X
X	    /* If the region is already initialized, check whether it is
X	     * allowed to grow the virtuell address space of the process by
X	     * btoc(memDesc.length) pages, before attaching it.
X	     */
X
X	    if(Reg_p->r_pgsz > 0) {
X
X	    	if(chkpgrowth(btoc(memDesc.length)) < 0) {
X			regrele(Reg_p);
X			u.u_error = ENOMEM;
X			break;
X	    	}
X	    }
X
X	    /* Attach region to process, R/O or R/W. Will fail if vaddr is
X	     * not a multiple of SHMLBA (= MMAPLBA, 4MB on a i386).
X	     */
X	    if(mode & FWRITE)
X		accmode = SEG_RW;
X	    else
X		accmode = SEG_RO;
X
X	    if((PReg_p = attachreg(Reg_p, &u, memDesc.vaddr, PT_SHMEM, accmode))
X		       == NULL) {
X		
X		/* If attaching failed and region is already initialized,
X		 * release it. Otherwise free it again.
X		 */
X		if(Reg_p->r_pgsz > 0)
X		    regrele(Reg_p);
X		else
X		    freereg(Reg_p);
X		break;
X	    }
X	
X
X	    /* If region is new allocated, grow region without allocating
X	     * swapable memory (DBD_NONE prevents decrementing of availsmem
X	     * and availrmem), i.e. allocate only page tables and dbd tables.
X	     * Then map the physical memory into it.
X	     * But check whether it is allowed to grow the virtuell address
X	     * space of the process by btoc(memDesc.length) pages before.
X	     */
X	    if(Reg_p->r_pgsz == 0) {	   
X
X	    	if(chkpgrowth(btoc(memDesc.length)) < 0) {
X		    detachreg(PReg_p, &u);
X		    u.u_error = ENOMEM;
X		    break;
X	    	}
X
X	    	if(growreg(PReg_p, btoc(memDesc.length), DBD_NONE) < 0) {
X		    detachreg(PReg_p, &u);
X		    u.u_error = ENOMEM;
X		    break;
X	    	}
X
X	    
X	    	/* Map physical memory into virtuell address space of process,
X		 * i.e. modify page tables and dbd tables.
X	    	 * I could also use mappages() here, but so I don't have the
X	    	 * overhead of it and know what I do.
X	    	 *
X	    	 * Linear address:
X	    	 *          +----------+----------+------------+
X	    	 *          |   ptnum  |  pnum    | byte off.  |
X	    	 *          +----------+----------+------------+
X	    	 *               10        10           12
X	    	 */
X	    	pmem = (paddr_t)memDesc.physaddr;
X
X	    	for(off = 0; off < memDesc.length; off += NBPP) {
X
X		    pte = (pde_t *)((uint)Reg_p->r_list[ptnum(off)] & PG_ADDR)
X		          + pnum(off);
X		    pte->pgi.pg_pde = (pmem & PG_ADDR) |
X				               PG_LOCK | PTE_RW | PG_P;
X		/*
X		 * SCO does page locking per-pfdat, not per-page table entry
X		 * according to SCO's <sys/immu.h>. Also pg_setlock(),
X		 * pg_clrlock(), and pg_islocked() are not macros, but
X		 * functions on SCO now. Assumed they changed not the
X		 * parameter of the original macro (I don't believe it,
X		 * would had a lot more changes in the kernel required...),
X		 * following would lock the page in core:
#ifdef SCO
X		    pg_setlock(pte);
#endif
X		 * It's uncommented because it's not tested yet.
X		 */
X
X		    dbdte 	    = finddbd(Reg_p, pte);
X		    dbdte->dbd_type = DBD_IOMAP;
X
X		    /* Move to next physical page. */
X		    pmem += NBPP;
X	    	}
X
X	    	/* Region is initialized. Don't free region on last detach.
X	         */
X	    	Reg_p->r_flags   |= RG_DONE | RG_NOFREE;
X		Reg_p->r_dbdnone =  0;
X
X		mmapreg[map_cnt].physaddr = (paddr_t)memDesc.physaddr;
X		mmapreg[map_cnt++].Reg_p  = Reg_p;
X
X	    } /* Region size still zero */
X
X	    /* Increase number of attached shared memory regions.
X	     */
X	    u.u_nshmseg++;
X
X 	    /* Only count up this to prevent swapping. Maybe it's not
X	     * necessary.
X	     */
X            Reg_p->r_noswapcnt++;  
X
X	    /* Release region and return.
X	     */
X	    regrele(Reg_p);
X	    u.u_rval1 = (int)memDesc.vaddr;
X	    break;
X
X
X	/* Unmap region from physical address space and try to free
X	 * it.
X         */
X	case UNMAPRM:
X	     FreeReg = True;
X
X	/* Unmap region from physical address space.
X	 */
X	case UNMAP:
X
X	    /* Check whether the given vaddr is a valid virtuell address
X	     * of a shared memory region of this process, i.e. look for it
X	     * in the process table of pregions.
X	     */
X	    PReg_p = u.u_procp->p_region;
X
X	    while(PReg_p->p_reg != NULL) {
X
X		if(PReg_p->p_type == PT_SHMEM  &&
X				 PReg_p->p_regva == (caddr_t)arg)
X		     break;
X		PReg_p++;
X	    }
X
X	    if(PReg_p->p_reg == NULL) {
X		u.u_error = EINVAL;
X		break;
X	    }
X
X	    /* Check whether the this is really one of our I/O regions,
X	     * i.e. region must be known to us.
X	     */
X
X	    for(i = 0; i < map_cnt; i++) {
X		if(PReg_p->p_reg == mmapreg[i].Reg_p)
X		     break;
X	    }
X	    if(i == map_cnt) {
X		u.u_error = EINVAL;
X		break;
X	    }
X
X	    Reg_p = PReg_p->p_reg;
X	    reglock(Reg_p);
X	    detachreg(PReg_p, &u);
X	    u.u_nshmseg--;
X
X	    /* If FREEREG is requested and no other user is pointing
X	     * at the region free it and remove it from the internal
X	     * list.
X	     */
X	    if(FreeReg && (Reg_p->r_refcnt == 0)) {
X	    	reglock(Reg_p);
X		Reg_p->r_flags  &= ~RG_NOFREE;
X		freereg(Reg_p);
X		for(i = i; i < map_cnt; i++)
X		    mmapreg[i] = mmapreg[i+1];
X		map_cnt--;
X	    }
X	    break;
X
X
X	/* Return number of currently memory mapped I/O regions.
X	 */
X	case GETNMMREG:
X	    u.u_rval1 = map_cnt;
X	    break;
X
X	/* Return information block about currently memory mapped I/O
X	 * regions.
X	 */
X	case GETMMREG:
X
X	    for(i = 0; i < map_cnt; i++) {
X		ibuf.physaddr = mmapreg[i].physaddr;
X		ibuf.length   = ctob(mmapreg[i].Reg_p->r_pgsz);
X		ibuf.refcnt   = mmapreg[i].Reg_p->r_refcnt;
X		if(copyout(&ibuf, arg, sizeof(ibuf)) == -1) {
X		     u.u_error = EFAULT;
X		     return;
X		}
X		arg += sizeof(ibuf);
X	    }
X	    break;
X
X
X	/* Return version number
X	 */
X	case GETVERSION:
X	    u.u_rval1 = MMAPVERSION;
X	    break;
X
X
X	default:
X	    u.u_error = EINVAL;
X	    break;
X
X    }
}
X
X
/* Find a virtual mapping address.
X */
static caddr_t FindVirtAddr(size)
X    uint size;
{
X    register caddr_t   vregaddr;
X    register caddr_t   vmapaddr		= (caddr_t)UVMMAP;
X    register preg_t   *preg_p   	= u.u_procp->p_region;
X
X    /* Go through the process regions table...
X     */
X    while(preg_p->p_reg != NULL) {
X
#ifdef DEBUG        
X        printf("MMAP: Try vmapaddr %x\n", vmapaddr);
#endif
X	/* If region grows down, use previous MMAPLBA boundary address as
X	 * starting address. Round up the 0x????3fffc aligned (ending) address
X	 * before.
X	 */
X	if((preg_p->p_reg)->r_flags & RG_DOWN)
X	    vregaddr = prev_ba(next_ba(preg_p->p_regva) -
X				ctob((preg_p->p_reg)->r_pgsz));
X	else
X	    vregaddr = preg_p->p_regva;
#ifdef DEBUG
X        printf("MMAP: vregaddr = %x\n", vregaddr);
#endif
X
X	/* Search for process region with address above the desired 
X	 * mapping address.
X	 */
X        if(vmapaddr > vregaddr) {
X	    preg_p++;
X	    continue;
X        }
X
X	/* If address is already in use try next address at MMAPLBA boundary
X	 * after end of this region.
X	 */
X	if(vmapaddr == vregaddr) {
X	    vmapaddr = next_ba(vregaddr + ctob((preg_p->p_reg)->r_pgsz));
X	    preg_p++;
X	    continue;
X	}
X
X	/* If desired start and end addresses are below this region
X	 * use this address for mapping, otherwise try next address at
X	 * MMAPLBA boundary after end of this region.
X	 */
X	if((vmapaddr + size - 1) < vregaddr) {
#ifdef DEBUG
X		printf("MMAP: Take %x\n", vmapaddr);
#endif
X		return vmapaddr;
X	}
X	vmapaddr = next_ba(vregaddr + ctob((preg_p->p_reg)->r_pgsz));
X	preg_p++;
X    }    
X
X    /* If no hole between process regions found, but current vmapaddr
X     * (end address) is still below the maximal possible user virtual
X     * address, then use it.
X     */
X    if((vmapaddr + size - 1) < (caddr_t)MAXUVADR)
X	return vmapaddr;
X    
X    /* Found no hole... */
X    return NULL;
}
X
SHAR_EOF
chmod 0644 mmap-2.2.3/mmap.c ||
echo 'restore of mmap-2.2.3/mmap.c failed'
Wc_c="`wc -c < 'mmap-2.2.3/mmap.c'`"
test 15554 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/mmap.c: original size 15554, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/mmap.h ==============
if test -f 'mmap-2.2.3/mmap.h' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/mmap.h (File already exists)'
else
echo 'x - extracting mmap-2.2.3/mmap.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmap.h' &&
X
/* This file contains various defines for the MMAP driver.
X *
X * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
X * 
X * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
X */
X
#if !defined (M_I286)
#ident	"@(#)mmap.h - MMAP v2.2.3, Copyright (c) Thomas Wolfram 1993"
#endif
X
#define MMAPLBA  ctob(stoc(1))  /* segment low boundary address multiple */
X                        	/* (MMAPLBA must be a power of 2)        */
X				/* MMAPLBA = 4MB on a i386		 */
X
/* base of memory mapped I/O regions, this is 256MB beyond UVSHM */
#define UVMMAP ((unsigned)0x90000000L)
X
/* Maximal number of memory mapped I/O regions. Can be overwritten
X * by /etc/conf/cf.d/stune.
X */
#ifndef NMMAPREG
#define NMMAPREG 64
#endif
X
/* Ioctl's
X */
#define MMAP_IOCTL	('M'<<8)
#define MAP		(MMAP_IOCTL|0)
#define UNMAP		(MMAP_IOCTL|1)
#define GETNMMREG	(MMAP_IOCTL|2)
#define GETMMREG	(MMAP_IOCTL|3)
#define UNMAPRM		(MMAP_IOCTL|4)
#define GETVERSION	(MMAP_IOCTL|5)
X
/* Memory mapped I/O region description.
X */
typedef struct {
X	paddr_t  physaddr;	/* physical address of region		*/
X	reg_t   *Reg_p;		/* pointer to region structure		*/
} mmapreg_t;
X
/* Memory mapped I/O region description for GETMMREG ioctl.
X */
typedef struct mmapinfo {
X	paddr_t physaddr;	/* physical address of region   	*/
X	long    length;		/* size of region in bytes		*/
X	short   refcnt;		/* number of users pointing at region	*/
} mmapinfo_t;
X
SHAR_EOF
chmod 0644 mmap-2.2.3/mmap.h ||
echo 'restore of mmap-2.2.3/mmap.h failed'
Wc_c="`wc -c < 'mmap-2.2.3/mmap.h'`"
test 1422 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/mmap.h: original size 1422, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/mmap.man ==============
if test -f 'mmap-2.2.3/mmap.man' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/mmap.man (File already exists)'
else
echo 'x - extracting mmap-2.2.3/mmap.man (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmap.man' &&
.\" Copyright (c) 1993 by Thomas Wolfram
.TH mmap 7L "2.2.3, 22 November 1993" "Version 2.2.3"
.de BP
.sp
.ti -.2i
\(**
..
.SH NAME
mmap \- \fBMMAP\fP ioctl commands (memory mapped I/O support)
.SH SYNOPSIS
.br
#include <sys/types.h>
.br
#ifndef SCO
.br
#include <sys/at_ansi.h>
.br
#include <sys/kd.h>
.br
#else
.br
#include <sys/vtkd.h>
.br
#endif
.br
#include <sys/sysmacros.h>
.br
#include <sys/immu.h>
.br
#include <sys/region.h>
.br
#include <sys/mmap.h>
.P
int ioctl(fildes, command, arg);
.br
int fildes, command;
.SH DESCRIPTION
.I MMAP
is a pseudo device driver which provides memory mapped I/O for user processes,
i.e. direct mapping of physical memory ranges into the user's virtual address
space for fast access. It is especially useful for accessing the linear frame
buffers of certain graphic hardware from the user level.
.P
To execute the \fIMMAP ioctl\fR commands \fIfildes\fR must be an open file
descriptor [see \fIopen(2)\fR] that refers to the special character device
\fI/dev/mmap\fR. The effective user ID of the calling process must be
superuser.
.br
The driver uses shared memory type regions for mapping. So the maximum
number of regions the driver can attach to a process is limited by
the maximum number of shared memory regions which can be attached to
the process [see \fIshmget(2), shmop(2), shmctl(2)\fR]. This number
is a tunable system parameter (\fISHMSEG\fR) [see \fIkconfig(1),
idtune(1M)\fR].
.br
The number of regions which the driver is able to map system-wide (i.e. to
all running processes) is limited too. This number is also a tunable
system parameter (\fINMMAPREG\fR).
.P
Note, the \fIMMAP\fR driver grows the virtual address space of the calling
process by itself. Allocating address space before with \fImalloc(3)\fR
isn't necessary and will not work.
.br
The mapping regions allocated by the driver will always be sharable, never
private to a process. Regions can be of type read/write or read/only.
This depends from the \fImode\fR \fI/dev/mmap\fR is opened [see \fIopen(2)\fR].
Once a region is allocated and mapped to a process it will normally remain
in the system (until reboot) even if the last process which pointed at it
detaches it from its address space. (This is not much waste since
the \fIMMAP\fR driver allocates no physical pages for the mapping region.)
But with the \fIUNMAPRM\fR ioctl removing after unmapping can be
requested [see below and \fImmaprm(1L)\fR].
If a process wants to map in the same memory range like another one (e.g. if
it's the same program which is running again) it will be attached with the
already existing region by the driver. Same applies if the processes which
requests the same mapping are running simultaneously.
.SS Ioctl Calls
The following ioctl commands can be used:
.IP \fBMAP\fP 2
This call maps physical memory into the virtual address space of the
user process. The following structure, defined in <sys/kd.h> [see
\fIdisplay(7)\fR], is pointed to by the argument \fIarg\fR to the ioctl:
.IP
struct kd_memloc {
.br
X	char  *vaddr;     /* virtual address to map to */
.br
X	char  *physaddr;  /* physical address to map from */
.br
X	long  length;     /* size in bytes to map */
.br
X	long  ioflg;      /* not used by the \fIMMAP\fR driver */
.br
};
.IP "" 2
The \fIvaddr\fR argument is the linear address in the process where the
physical memory range will appear. This address must be on a boundary
specified by the machine dependant constant \fIMMAPLBA\fR, defined in
<sys/mmap.h>. If \fIvaddr\fR is equal to zero the address is selected by
the driver itself.
.br
The \fIphysaddr\fR argument is the physical address of the memory range
that will be mapped in. It must be on a page boundary.
.br
The \fIlength\fR argument is the size of the memory range that will be
mapped in. It will be rounded up to a multiple of the size of a page
by the driver.
.br
On success the ioctl will return the virtual address where the memory
is mapped in. It will fail if one or more of the following is true:
.RS 4
.IP [EPERM] 15
The effective user ID of the calling process is not superuser.
.IP [EFAULT] 15
The user address pointed to by \fIarg\fR is illegal.
.IP [EINVAL] 15
The \fIvaddr\fR argument is not equal to zero, and the value is an illegal
address (not on a MMAPLBA boundary, already used in the process or not
below \fIMAXUVADR\fR, as defined in <sys/immu.h>).
.IP [EINVAL] 15
The \fIphysaddr\fR argument is not on a page boundary.
.IP [ENOMEM] 15
The \fIvaddr\fR argument is equal to zero and the driver is not able
to find a proper region in the user's address space where the memory
range would fit in.
.IP [ENOMEM] 15
The size of the user's virtual address space would exceed the system-imposed
limit.
.IP [ENOMEM] 15
Not enough system internal space available to grow the user's virtual
address space.
.IP [EMFILE] 15
The number of shared memory segments attached to the calling process would
exceed the system-imposed limit.
.IP [EMFILE] 15
The number of all memory mapped regions in the system would exceed the
driver-imposed limit.
.RE 1
.IP \fBUNMAP\fP 2
This call unmaps previously mapped physical memory from the calling process.
The argument \fIarg\fR to the ioctl must be the virtual address as
returned by the previous \fIMAP\fR ioctl.
.br
It will fail if one or more of the following is true:
.RS 4
.IP [EPERM] 15
The effective user ID of the calling process is not superuser.
.IP [EINVAL] 15
If \fIarg\fR is not the start address of a region mapped by the driver to
the calling process.
.RE 1
.IP \fBUNMAPRM\fP 2
Same like \fIUNMAP\fR but removes the concerning region from the systems
internal list, if no other process is still using it [see \fImmaprm(1L)\fR].
.IP \fBGETNMMREG\fP 2
This call returns the number of the memory mapped I/O regions which
exists currently in the system [\fIsee mmapstat(1L)\fR]. It requires no
argument. It will fail if one or more of the following is true:
.RS 4
.IP [EPERM] 15
The effective user ID of the calling process is not superuser.
.RE 1
.IP \fBGETMMREG\fP 2
This call returns the current status of the \fIMMAP\fR driver. The
argument \fIarg\fR must be a pointer to an array of elements of
the following type (defined in <sys/mmap.h>):
.IP
typedef struct mmapinfo {
.br
X	paddr_t physaddr; /* physical address */
.br
X	long  length;     /* size in bytes */
.br
X	short refcnt;     /* number of users */
.br
X	/* pointing currently at this region */
.br
} mmapinfo_t;
.IP "" 2
which is filled by the driver for every region currently exists.
The array must have as much elements as the number returned by the
\fIGETNMMREG\fR ioctl states [see \fImmapstat(1L)\fR].
The command will fail if one or more of the following is true:
.RS 4
.IP [EPERM] 15
The effective user ID of the calling process is not superuser.
.IP [EFAULT] 15
The user address pointed to by \fIarg\fR is illegal.
.IP "" 2
.RE 1
.IP \fBGETVERSION\fP 2
Returns version number of driver, e.g. version 2.2.1 would be returned
as 0x0221.
.SH FILES
.IP \fI/dev/mmap\fR 2
Character device interface to the driver.
.SH "SEE ALSO"
open(2), ioctl(2), display(7), shmget(2), shmop(2), shmctl(2), kconfig(1),
idtune(1M), intro(2), mmapstat(1L), mmaprm(1L).
.SH DIAGNOSTICS
Upon sucessful completion, the return value is as follows:
.RS 5
.P
The \fIMAP\fR ioctl returns the user's address where the physical memory
is mapped in.
.P
The \fIUNMAP\fR and \fIUNMAPRM\fR ioctl's return a value of 0. 
.P
The \fIGETNMMREG\fR ioctl returns the number of memory mapped I/O regions
which exists currently in the system.
.P
The \fIGETMMREG\fR ioctl returns a value of 0. 
.P
The \fIGETVERSION\fR ioctl returns the version number. 
.RE 1
.P
Otherwise, a value of -1 is returned, and \fIerrno\fR [see \fIintro(2)\fR]
is set to indicate the error.
.SH BUGS
Please report bugs to:
.B wolf@prz.tu-berlin.de
or
.BR thomas@aeon.in-berlin.de .
.SH COPYING
Copyright (c) 1993 Thomas Wolfram
.SH AUTHOR
Thomas Wolfram
SHAR_EOF
chmod 0644 mmap-2.2.3/mmap.man ||
echo 'restore of mmap-2.2.3/mmap.man failed'
Wc_c="`wc -c < 'mmap-2.2.3/mmap.man'`"
test 7901 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/mmap.man: original size 7901, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/mmaprm.1 ==============
if test -f 'mmap-2.2.3/mmaprm.1' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/mmaprm.1 (File already exists)'
else
echo 'x - extracting mmap-2.2.3/mmaprm.1 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmaprm.1' &&
X
X
X
X          mmaprm(1L)                   386/ix                    mmaprm(1L)
X
X
X
X          NAME
X               mmaprm - remove a memory mapped I/O region of the MMAP
X               driver
X
X          SYNOPSIS
X               mmaprm #
X
X          DESCRIPTION
X               The mmaprm removes a memory mapped I/O region number # from
X               the MMAP driver's [see mmap(7)] internal list and frees also
X               the concerning system resource. The command will fail if the
X               region is still used by other processes.  The number # is
X               the number as returned by the mmapstat(1L) command.
X
X          FILES
X               /dev/mmap
X                 Character device interface to the MMAP driver.
X
X          SEE ALSO
X               mmap(7L), mmapstat(1L).
X
X          BUGS
X               Please report bugs to:  wolf@prz.tu-berlin.de or
X               thomas@aeon.in-berlin.de.
X
X          COPYING
X               Copyright (c) 1993 Thomas Wolfram
X
X          AUTHOR
X               Thomas Wolfram
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X          Rev. 2.2.3, 22 November 1993                               Page 1
X
X
X
SHAR_EOF
chmod 0644 mmap-2.2.3/mmaprm.1 ||
echo 'restore of mmap-2.2.3/mmaprm.1 failed'
Wc_c="`wc -c < 'mmap-2.2.3/mmaprm.1'`"
test 1495 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/mmaprm.1: original size 1495, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/mmaprm.c ==============
if test -f 'mmap-2.2.3/mmaprm.c' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/mmaprm.c (File already exists)'
else
echo 'x - extracting mmap-2.2.3/mmaprm.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmaprm.c' &&
/*
X * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
X *
X * Permission to use, copy, modify, distribute, and sell this software and its
X * documentation for any purpose is hereby granted without fee, provided that
X * the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of Thomas Wolfram be used in
X * advertising or publicity pertaining to distribution of the software without
X * specific, written prior permission.  Thomas Wolfram makes no
X * representations about the suitability of this software for any purpose.
X * It is provided "as is" without express or implied warranty.
X *
X * THOMAS WOLFRAM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
X * EVENT SHALL THOMAS WOLFRAM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
X * PERFORMANCE OF THIS SOFTWARE.
X *
X * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
X */
X
/* mmaprm
X * ------
X * Free mmap I/O regions from drivers internal list.
X */
X
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/fcntl.h>
X
#ifndef SCO
#include <sys/at_ansi.h>
#include <sys/kd.h>
#else
#include <sys/vtkd.h>
#endif
#include <sys/sysmacros.h>
#include <sys/immu.h>
#include <sys/region.h>
X
#include <sys/mmap.h>
X
X
void ErrorExit(s)
X    char *s;
{
X    perror(s);
X    exit(1);
}
X
X
main(argc, argv)
X   int argc;
X   char **argv;
{
X   int mmap, regnr, nmmreg;
X   unsigned char eoi;
X   mmapinfo_t *ibuf;
X   caddr_t mapaddr;
X   struct kd_memloc memDesc;
X
X   if(argc != 2) {
X	fprintf(stderr, "usage: %s n1\n", argv[0]);
X	exit(1);
X   }
X
X
X   if((mmap = open("/dev/mmap", O_RDONLY)) == -1)
X	ErrorExit(argv[0]);
X
X   if(ioctl(mmap, GETVERSION) < 0x0221) {
X	fprintf(stderr, "%s: MMAP 2.2.1 or above required.\n", argv[0]);
X	exit(1);
X   }
X
X   if((nmmreg = ioctl(mmap, GETNMMREG)) == -1)
X	ErrorExit(argv[0]);
X
X   if(nmmreg == 0) {
X	fprintf(stderr, "%s: No physical memory mapped currently.\n", argv[0]);
X	exit(1);
X   }
X
X   if(!sscanf(argv[1], "%d%c\n", &regnr, &eoi)) {
X	fprintf(stderr, "%s: Invalid region number\n", argv[0]);
X	exit(1);
X   }
X
X   if(eoi != '\0' || regnr < 0 || regnr >= nmmreg) {
X	fprintf(stderr, "%s: Invalid region number\n", argv[0]);
X	exit(1);
X   }
X   
X   if((ibuf = (mmapinfo_t *)malloc(nmmreg*sizeof(mmapinfo_t))) == NULL)
X	ErrorExit(argv[0]);
X
X
X   if(ioctl(mmap, GETMMREG, ibuf) == -1)
X	ErrorExit(argv[0]);
X
X
X   memDesc.physaddr = (caddr_t)ibuf[regnr].physaddr;
X   memDesc.length   = ibuf[regnr].length;
X   memDesc.vaddr    = (caddr_t)0;
X
X   printf("Try removing memory mapped I/O region %d from system...\n", regnr);
X   printf("[%d] Physical Address = 0x%08X\n", regnr, memDesc.physaddr);
X   printf("[%d] Size             = %dk\n",    regnr, memDesc.length/1024);
X
X   if(ibuf[regnr].refcnt > 0) {
X	fprintf(stderr, "Region %d still in use. Cannot remove.\n", regnr);
X	exit(1);
X   }
X
X   if((mapaddr = (caddr_t)ioctl(mmap, MAP, &memDesc)) == (caddr_t)-1)
X	ErrorExit(argv[0]);
X
X   ioctl(mmap, UNMAPRM, mapaddr);
X   printf("Removed.\n");
X
}
X
SHAR_EOF
chmod 0644 mmap-2.2.3/mmaprm.c ||
echo 'restore of mmap-2.2.3/mmaprm.c failed'
Wc_c="`wc -c < 'mmap-2.2.3/mmaprm.c'`"
test 3346 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/mmaprm.c: original size 3346, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/mmaprm.man ==============
if test -f 'mmap-2.2.3/mmaprm.man' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/mmaprm.man (File already exists)'
else
echo 'x - extracting mmap-2.2.3/mmaprm.man (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmaprm.man' &&
.\" Copyright (c) 1993 by Thomas Wolfram
.TH mmaprm 1L "2.2.3, 22 November 1993" "Version 2.2.3"
.de BP
.sp
.ti -.2i
\(**
..
.SH NAME
mmaprm \- remove a memory mapped I/O region of the \fBMMAP\fP driver
.SH SYNOPSIS
mmaprm #
.SH DESCRIPTION
The \fImmaprm\fR removes a memory mapped I/O region number # from
the \fIMMAP\fR driver's [see \fImmap(7)\fR] internal list and frees
also the concerning system resource. The command will fail if the
region is still used by other processes.
The number # is the number as returned by the \fImmapstat(1L)\fR command.
.SH FILES
.IP \fI/dev/mmap\fR 2
Character device interface to the \fIMMAP\fR driver.
.SH "SEE ALSO"
mmap(7L), mmapstat(1L).
.SH BUGS
Please report bugs to:
.B wolf@prz.tu-berlin.de
or
.BR thomas@aeon.in-berlin.de .
.SH COPYING
Copyright (c) 1993 Thomas Wolfram
.SH AUTHOR
Thomas Wolfram
SHAR_EOF
chmod 0644 mmap-2.2.3/mmaprm.man ||
echo 'restore of mmap-2.2.3/mmaprm.man failed'
Wc_c="`wc -c < 'mmap-2.2.3/mmaprm.man'`"
test 843 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/mmaprm.man: original size 843, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/mmapstat.1 ==============
if test -f 'mmap-2.2.3/mmapstat.1' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/mmapstat.1 (File already exists)'
else
echo 'x - extracting mmap-2.2.3/mmapstat.1 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmapstat.1' &&
X
X
X
X          mmapstat(1L)                 386/ix                  mmapstat(1L)
X
X
X
X          NAME
X               mmapstat - print status of the MMAP driver
X
X          SYNOPSIS
X               mmapstat
X
X          DESCRIPTION
X               The mmapstat command prints the current status of the MMAP
X               driver [see mmap(7)].
X               For every memory mapped I/O region which exists currently in
X               the system mmapstat prints the physical address, the size in
X               kByte and the number of processes which currently uses this
X               region.
X
X          FILES
X               /dev/mmap
X                 Character device interface to the MMAP driver.
X
X          SEE ALSO
X               mmap(7L), mmaprm(1L).
X
X          BUGS
X               Please report bugs to:  wolf@prz.tu-berlin.de or
X               thomas@aeon.in-berlin.de.
X
X          COPYING
X               Copyright (c) 1993 Thomas Wolfram
X
X          AUTHOR
X               Thomas Wolfram
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X          Rev. 2.2.3, 22 November 1993                               Page 1
X
X
X
SHAR_EOF
chmod 0644 mmap-2.2.3/mmapstat.1 ||
echo 'restore of mmap-2.2.3/mmapstat.1 failed'
Wc_c="`wc -c < 'mmap-2.2.3/mmapstat.1'`"
test 1453 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/mmapstat.1: original size 1453, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/mmapstat.c ==============
if test -f 'mmap-2.2.3/mmapstat.c' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/mmapstat.c (File already exists)'
else
echo 'x - extracting mmap-2.2.3/mmapstat.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmapstat.c' &&
/*
X * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
X *
X * Permission to use, copy, modify, distribute, and sell this software and its
X * documentation for any purpose is hereby granted without fee, provided that
X * the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of Thomas Wolfram be used in
X * advertising or publicity pertaining to distribution of the software without
X * specific, written prior permission.  Thomas Wolfram makes no
X * representations about the suitability of this software for any purpose.
X * It is provided "as is" without express or implied warranty.
X *
X * THOMAS WOLFRAM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
X * EVENT SHALL THOMAS WOLFRAM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
X * PERFORMANCE OF THIS SOFTWARE.
X *
X * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
X */
X
/* mmapinfo
X * --------
X * Gets the status of the MMAP driver.
X */
X
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <time.h>
X
#ifndef SCO
#include <sys/at_ansi.h>
#include <sys/kd.h>
#else
#include <sys/vtkd.h>
#endif
#include <sys/sysmacros.h>
#include <sys/immu.h>
#include <sys/region.h>
X
#include <sys/mmap.h>
X
X
void ErrorExit(s)
X    char *s;
{
X    perror(s);
X    exit(1);
}
X
X
main(argc, argv)
X   int argc;
X   char **argv;
{
X   int mmap, nmmreg, i;
X   mmapinfo_t *ibuf;
X   time_t clock;
X
X
X   if((mmap = open("/dev/mmap", O_RDONLY)) == -1)
X	ErrorExit(argv[0]);
X
X   if((nmmreg = ioctl(mmap, GETNMMREG)) == -1)
X	ErrorExit(argv[0]);
X
X   time(&clock);
X
X   printf("Currently memory mapped I/O regions as of %s", ctime(&clock));
X   printf("#      Physical Address     Size      Reference Count\n");
X
X   if(nmmreg == 0) {
X	printf("\nNo physical memory mapped currently.\n\n");
X	exit(1);
X   }
X
X   
X   if((ibuf = (mmapinfo_t *)malloc(nmmreg*sizeof(mmapinfo_t))) == NULL)
X	ErrorExit(argv[0]);
X
X   if(ioctl(mmap, GETMMREG, ibuf) == -1)
X	ErrorExit(argv[0]);
X
X   for(i = 0; i < nmmreg; i++)
X   printf("%-4d   0x%08X         %5dk                %5d\n",
X	  i, ibuf[i].physaddr, ibuf[i].length/1024, ibuf[i].refcnt);
X   printf("\n");
X
}
X
SHAR_EOF
chmod 0644 mmap-2.2.3/mmapstat.c ||
echo 'restore of mmap-2.2.3/mmapstat.c failed'
Wc_c="`wc -c < 'mmap-2.2.3/mmapstat.c'`"
test 2531 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/mmapstat.c: original size 2531, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/mmapstat.man ==============
if test -f 'mmap-2.2.3/mmapstat.man' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/mmapstat.man (File already exists)'
else
echo 'x - extracting mmap-2.2.3/mmapstat.man (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmapstat.man' &&
.\" Copyright (c) 1993 by Thomas Wolfram
.TH mmapstat 1L "2.2.3, 22 November 1993" "Version 2.2.3"
.de BP
.sp
.ti -.2i
\(**
..
.SH NAME
mmapstat \- print status of the \fBMMAP\fP driver
.SH SYNOPSIS
mmapstat
.SH DESCRIPTION
The \fImmapstat\fR command prints the current status of the \fIMMAP\fR
driver [see \fImmap(7)\fR].
.br
For every memory mapped I/O region which exists currently in the system
\fImmapstat\fR prints the physical address, the size in kByte and
the number of processes which currently uses this region.
.SH FILES
.IP \fI/dev/mmap\fR 2
Character device interface to the \fIMMAP\fR driver.
.SH "SEE ALSO"
mmap(7L), mmaprm(1L).
.SH BUGS
Please report bugs to:
.B wolf@prz.tu-berlin.de
or
.BR thomas@aeon.in-berlin.de .
.SH COPYING
Copyright (c) 1993 Thomas Wolfram
.SH AUTHOR
Thomas Wolfram
SHAR_EOF
chmod 0644 mmap-2.2.3/mmapstat.man ||
echo 'restore of mmap-2.2.3/mmapstat.man failed'
Wc_c="`wc -c < 'mmap-2.2.3/mmapstat.man'`"
test 808 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/mmapstat.man: original size 808, current size' "$Wc_c"
fi
# ============= mmap-2.2.3/tstmap.c ==============
if test -f 'mmap-2.2.3/tstmap.c' -a X"$1" != X"-c"; then
	echo 'x - skipping mmap-2.2.3/tstmap.c (File already exists)'
else
echo 'x - extracting mmap-2.2.3/tstmap.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/tstmap.c' &&
/*
X * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
X *
X * Permission to use, copy, modify, distribute, and sell this software and its
X * documentation for any purpose is hereby granted without fee, provided that
X * the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation, and that the name of Thomas Wolfram be used in
X * advertising or publicity pertaining to distribution of the software without
X * specific, written prior permission.  Thomas Wolfram makes no
X * representations about the suitability of this software for any purpose.
X * It is provided "as is" without express or implied warranty.
X *
X * THOMAS WOLFRAM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
X * EVENT SHALL THOMAS WOLFRAM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
X * PERFORMANCE OF THIS SOFTWARE.
X *
X * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
X */
X
/* Test program for MMAP driver, maps the main bios into the process'
X * address space.
X */
X
#include <stdio.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <errno.h>
X
#ifndef SCO
#include <sys/at_ansi.h>
#include <sys/kd.h>
#else
#include <sys/vtkd.h>
#endif
#include <sys/sysmacros.h>
#include <sys/immu.h>
#include <sys/region.h>
X
#include <sys/mmap.h>
X
#define MAP_SIZE 64*1024	/* 64k 		*/
#define PHYS_ADDR 0xF0000	/* Main BIOS 	*/
#define VIRT_ADDR 0
X
main(argc, argv)
X   int argc;
X   char **argv;
{
X   int i;
X   int fm;
X   caddr_t mapaddr;
X   struct kd_memloc memDesc;
X
X   memDesc.vaddr    = (caddr_t)VIRT_ADDR;
X   memDesc.physaddr = (caddr_t)PHYS_ADDR;
X   memDesc.length   = MAP_SIZE;
X
X   if((fm = open("/dev/mmap", O_RDONLY)) == -1) {
X	perror(argv[0]);
X	exit(1);
X   }
X
X   printf("MAP main BIOS...\n");
X   if((mapaddr = (caddr_t)ioctl(fm, MAP, &memDesc)) == (caddr_t)-1) {
X	perror(argv[0]);
X	exit(1);
X   }
X
X   printf("Mapping addr = %x\n", mapaddr);
X
X   for(i=0; i < 80; i++)
X	printf("%c", mapaddr[i]);
X   printf("\n");
X
X   printf("UNMAP main BIOS...\n");
X   if(ioctl(fm, UNMAP, mapaddr) == -1) {
X	perror(argv[0]);
X	exit(1);
X   }
X   printf("Trying access after unmapping, should dump core...\n");
X   printf("*mapaddr = %02x\n", *(unsigned char *)mapaddr);
X
}
X
SHAR_EOF
chmod 0644 mmap-2.2.3/tstmap.c ||
echo 'restore of mmap-2.2.3/tstmap.c failed'
Wc_c="`wc -c < 'mmap-2.2.3/tstmap.c'`"
test 2539 -eq "$Wc_c" ||
	echo 'mmap-2.2.3/tstmap.c: original size 2539, current size' "$Wc_c"
fi
exit 0
