devpci for 3rd Ed.


Note: the 4th ed. devpnp supplies much of this same functionality, but is read only.

This little program allows me to read/write to random memory addresses
from userland.  Russ Cox indicated that he has something similar, but
since i wanted to learn how to write /dev/ stuff i decided to give it
a try myself...  I find it helpful when debugging vga (for example)
from serial console.  Maybe some of you will find it helpful for
other things :)

Something to note: it is unsafe to use peek and poke at the hardware
from userland.  There are so many ways to render your machine
inoperable that I'm not going to bother listing them here.  (Normally
a reboot fixes things, but...)  Don't take it out on me or on LANL if
your hardware chokes as a consequence of pcidev.  Do not attempt to
remove bread stuck in a plugged toaster with a knife either.
*shrug*...  You know all this, bot nevertheless you have been warned.

Pcidev (sorry, couldn't think of a better name) sits between you and
the hardware devices on your computer.  It allows the user to
read/write (standard inb, inw, inl, outb, outw, outl) using simple
shell scripts.

Pcidev could be found as a drive named #Z.  When bound to a directory
it presents itself as a sigle file named 'base'.  This file takes as
input a memory address, to which the user wants to write or read.  
Having been given an address, pcidev creates a directory named after 
the it and populates it with 6 files used for reading/writing, namely:

	inb -> read a byte
	inw -> read a word (16 bits)  
	inl -> read a long   

	outb -> write to the port (byte)
	outw -> short
	outl 	-> long

That's pretty much it.. It's really simple.

Here's a sample session with it:

----

% bind -a '#Z' /tmp/z
% cd /tmp/z
% ls
base
% echo 0x3cc > base  	# address should be a valid atol()-understandable string, 0xF, 0F, 15 -> all accepted
% ls
0x3cc				# 0x3cc is VGA's Miscellaneous Output Register
base
% cd 0x3cc
% ls
inb
inl
inw
outb
outl
outw
% cat inb
0xe3%				# no \n appended...
% cat inl
0xff0800e3%
% cd ..
% echo 0x80 > base
% rm 0x3cc
% ls
0x80				# a pci post-card. write-only
base
% cd 0x80
% echo 0xf > outb		# 0F shows on the device, 
% echo 14 > outb		# 0D shows on the device

----

That's about it.  The maximum addresses opened at a single time is 128.
Just rm some stuff to open up space (rm base will not work, of
course).

To compile a kernel with pcidev:

cd /sys/src/9/pc 
cp devpcidev.c .  
edit pcdisk and add 'pcidev' at the bottom of the 'dev' list 
mk 'CONF=9pcdisk' (or your favorite way ofdoing it) 
9fat:; cp 9pcdisk /n/9fat 
reboot...

Sorry, there is no man page for it, but there are no plans to put it
into the official distribution either :)

While discussing the 'design' with Ron Minnich another way of doing it
came up -- have a single file for input, another one for output and
manage the addresses with seek().  That way a 5-line C program could
read and report the entire status of a device.  I'm posting this
implementation because it's a bit more complex (dealing with
subdirectories, adding/deleting addresses) and not because it's
necessarily the better way to present files for inb and outb.

Files:

devpcidev.c


Last Modified: May 24 2002
andrey@lanl.gov