Edi Weitz <spamtrap@agharta.de> wrote:
+---------------
| rpw3@rpw3.org (Rob Warnock) wrote:
| > You want scary? I'll give you scary! Try peeking & poking hardware
| > registers from within CMUCL, heh-heh! MMAP some hardware into your
| > VM and then do (setf (system:sap-ref-32 (system:int-sap addr) 0)
| > new-value) [which in C is "*((u32*)(addr)+0) = new-value"]. I have a
| > whole toolkit of such low-level hacks that I use to do user-mode
| > debugging of hardware at my current POE.
|
| Sounds interesting. Do you have plans to make that publicly available?
+---------------
I guess I could put up the very lowest-level stuff (~150 lines), but:
1. It's more a set of patterns than a true "module". It all loads
into the "CL-USER" package, since that's where I usually work.
2. I don't have a fully fleshed-out example of how to use it for
something serious that's not proprietary to some current or
previous employer [most real applications involve page after page
of symbolic hardware register locations and bit definitions!].
3. The low-level stuff isn't very useful if you don't have any
interesting mmap'able hardware lying around you want to poke at... ;-}
4. If applied to introspection of CMUCL itself [I've been using it
for some of that lately], much of it is *NOT* GC-safe. You have
to be very sure you know what you're doing, and sometimes need
to do a (GC :FULL T) before starting a sequence of operations
[or maybe wrap a SYSTEM:WITHOUT-GCING around it].
5. Calling MAKE-LISP-OBJ with a bad argument can easily crash CMUCL,
and maybe your system.
6. You have to un CMUCL as root to mmap I/O memory space. Running
CMUCL as root can crash your system. YOU HAVE BEEN WARNED!
But if you really think anyone else would find it useful... ;-} ;-}
Most of it is just abbreviations and shortcuts to facilities
that are already in CMUCL for anyone who looks at the source,
e.g., MAKE-LISP-OBJ is just (IMPORT 'KERNEL:MAKE-LISP-OBJ);
R32 and W32 are just SYSTEM:SAP-REF-32 wrappers:
(defun r32 (addr)
(declare (optimize (speed 3) (debug 0) (safety 0)))
(system:sap-ref-32 (system:int-sap addr) 0))
(defun w32 (addr &rest values)
(declare (optimize (speed 3) (debug 0) (safety 0)))
(loop for i fixnum from 0 by 4
and v of-type (unsigned-byte 32) in values
do (setf (system:sap-ref-32 (system:int-sap addr) i) v))
(values))
R8/W8/R16/W16 are similar, and D32 (formerly named DUMP32) is just
a loop around R32 & FORMAT. My MMAP is just a thin wrapper around
UNIX:UNIX-MMAP with a slightly simplified calling sequence for the
cases I mostly use, a typical use being (MMAP "/dev/mem" PCI-BUS-ADDRESS T)
[where the PCI bus address is where some device register got mapped
by the BIOS, which on Linux you find out *manually* with "lspci"]:
(defun mmap (file offset length &optional write-p)
(let* ((ofs32 (if (zerop (logand offset #x80000000))
offset
(- offset #x100000000))) ; Fake up a "(signed-byte 32)"
(mode (logior #+linux unix::O_SYNC ; Not on BSD (*sigh*)
(if write-p unix:O_RDWR unix:O_RDONLY)))
(fd (unix:unix-open file mode 0)))
(if (not fd)
(error "Can't open ~s: ~s" file (unix:get-unix-error-msg))
(unwind-protect
(let ((mode (logior unix:PROT_READ
(if write-p unix:PROT_WRITE 0))))
(system:sap-int
(unix:unix-mmap nil length mode unix:MAP_SHARED fd ofs32)))
(unix:unix-close fd)))))
Is this level stuff really interesting to others?
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607