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.