;;; -*- Mode:LISP; Package:(WHY-PC GLOBAL); Base:10; Readtable:CL -*- ;;; Copyright LISP Machine, Inc. 1985 ;;; See filename "Copyright.Text" for ;;; licensing and release information. ;;; A simple function to call to learn the meaning of the output of ;;; the :WHY program. To use: Call the function WHY-PC:HALTS ;;; 1/24/85 13:16:40 -George Carrette ;;; this is a small program to be independant of any other diagnostics systems. (defvar *i-mem-symbol-table* nil "An alist of ( . pc) sorted by pc") (defvar *i-mem-symbol-tables* nil) (defpackage i-mem-symbols ;; have an independent package of the correct size, so as to make reading faster (:nicknames "I") (:prefix-name "I") (:size 4000.) (:use)) (defun halts (&optional previous-info &aux version) "This function decodes the output of the why program on the SDU Call this to find out what microcode procedures were being executed at the time a machine is halted." (format t "~&Please enter the version number of the microcode the machine was running.~%") (load-i-mem-symbols-for-ucode-version (setq version (or (prompt-and-read '(:number :input-radix 10. :or-nil t) "UCODE version (default ~D)> " si:%microcode-version-number) si:%microcode-version-number))) (format t "Please enter the PC's printed by the 'why' program. Entering -1 exits this program, <~:C> does a reprint.~%" #\Return) (do ((pc) (meanings previous-info) (symbol)) ((and (setq pc (prompt-and-read '(:number :input-radix 8. :or-nil t) "PC>")) (minusp pc)) (cond ((y-or-n-p "Do you want to save the results in a file?") (let ((comment (prompt-and-read '(:delimited-string :delimiter #\end) "~&Input a comment about the crash, ending with ~C~%" #\end)) (fname (prompt-and-read :pathname "~&Filename to save results to: "))) (with-open-file (stream fname :direction :output) (format stream "Running Microcode ~D~%~A~%~{~A~%~}" version comment meanings) (values meanings (truename stream))))) ('else meanings))) (cond ((null pc) (format t "~&For Ucode version ~D~%~{~A~%~}" version meanings)) ('else (setq symbol (lookup-i-mem-value pc *i-mem-symbol-table*)) (let ((st (format nil "At PC=#o~6,'0O machine is at ~O" pc symbol))) (format t "~&~A~%" st) (setq meanings (append meanings (list st)))))))) (defvar *lmc-sym-file* "SYS:UBIN;ULAMBDA LMC-SYM") (defun load-i-mem-symbols-for-ucode-version (n &aux temp) (cond ((setq temp (assoc n *i-mem-symbol-tables*)) (setq *i-mem-symbol-table* (cdr temp))) ('else (format t "~&;Loading symbol table for ucode ~D ..." n) (let ((time (time))) (with-open-file (stream (send (pathname *lmc-sym-file*) :new-version n)) (let ((*package* (find-package "I-MEM-SYMBOLS")) (*read-base* 8) (*readtable* (si:find-readtable-named "T"))) (do () ((eq -2 (read stream)))) (setq *i-mem-symbol-table* nil) (do ((symbol) (type) (value) (want-type (intern "I-MEM" package))) ((eq -1 (setq symbol (read stream)))) (setq type (read stream)) (setq value (read stream)) (cond ((eq type want-type) (push (cons symbol value) *i-mem-symbol-table*)))))) (setq *i-mem-symbol-table* (sort *i-mem-symbol-table* #'< :key #'cdr)) (push (cons n *i-mem-symbol-table*) *i-mem-symbol-tables*) (describe-package 'i-mem-symbols) (format t "~&;Took ~D seconds realtime~%" (/ (time-difference (time) time) 60.0))))) (format t "~&Using symbols for microcode version ~D.~%" n)) (defun lookup-i-mem-value (pc table) (do ((l (cdr table) (cdr l)) (previous (car table) (car l))) ((or (= pc (cdr previous)) (null l) (< (cdr previous) pc (cdr (car l)))) (if (= pc (cdr previous)) (car previous) `(,(car previous) + ,(- pc (cdr previous))))))) (defun iapropos (string) (subset #'(lambda (x) (string-search string (car x))) *i-mem-symbol-table*)) (defun active-ucode-table () (car (rassoc *i-mem-symbol-table* *i-mem-symbol-tables*))) (defun i-mem-dump-filename (version) (format nil "SYS:UBIN;ULAMBDA PC-LISTING ~D" version)) (defun i-mem-dump (&optional filename) (if filename (with-open-file (stream (i-mem-dump-filename (or (active-ucode-table) (ferror nil "no active ucode table"))) :out) (format stream "Directions: Look up the PC's of the WHY program in this table~ ~%Copyright 1985 Lisp Machine Inc. For internal use only!~%") (i-mem-dump-s stream)) (i-mem-dump-s standard-output))) (defun i-mem-dump-s (stream) (format stream "~&For microcode version ~D~%" (active-ucode-table)) (dolist (elem *i-mem-symbol-table*) (format stream "~6,'0o = ~A~%" (cdr elem) (car elem)))) (defun i-mem-dumpl (&rest versions) (mapcar #'(lambda (v) (let ((fname (i-mem-dump-filename v))) (cond ((probe-file fname) (format t "~&; Already exists: ~S~%" fname)) ('else (load-i-mem-symbols-for-ucode-version v) (format t "~&;Writing ~S~%" fname) (i-mem-dump t))) fname)) versions)) (defun cpcap (l dir) (dolist (x l) (with-open-file (in x) (with-open-file (out (merge-pathnames (format nil "UCODE-~D.t" (send (fs:parse-pathname x) :version)) dir) :out) (format t "~&; ~A ==> ~A~%" (send in :truename) (send out :truename)) (stream-copy-until-eof in out)))))