;;;-*- Mode:LISP; Package:LISP-INTERNALS; Base:10; Readtable:CL -*- ;;; ;;; Written by Youcef Bennour. ;;; ;;; ;;; COPIED FROM DJ:L.LAMBDA-DIAG;SMD-DISK.LISP ;;; ;;; routines to support shared disk -pace 3/21/84 (defun multibus-address-to-8086-ptr (adr) (dpb (ldb (byte 16. 4) adr) (byte 16. 16.) (ldb (byte 4. 0) adr))) (defun 8086-ptr-to-multibus-address (ptr) (+ (ash (ldb (byte 16. 16.) ptr) 4) (ldb (byte 16. 0) ptr) #xff000000)) ; first there is the share-iopb-chain, located at a well known place ; in multibus memory. The head of the chain is a structure that looks like: ; ; ptr-to-first-share-iopb - 4 byte 8086 address ; lock-byte - 1 byte - set to 0 if free, 1 if someone is looking at the chain ; debug-byte - 1 byte set to the debug level given to the share starter 8086 program (defconstant sharestruct-ptr #xff000080) (defconstant sharestruct-lock #xff000084) (defconstant sharestruct-debug-level #xff000085) (defconstant sharestruct-share-lock 0) (defconstant sharestruct-max-iopbs-offset 4) (defconstant sharestruct-current-iopb-offset 8.) (defconstant sharestruct-valid-table-offset 12.) (defconstant share-iopb-runme-offset 0) (defconstant share-iopb-slot-offset 4) (defconstant share-iopb-type-offset 8.) (defconstant share-iopb-iopb-offset 12.) (defconstant share-iopb-interrupt-offset 16.) (defun sharestruct-valid-p () (not (zerop (ldb (byte 20. 0) (read-8086-multibus-address sharestruct-ptr))))) ; these are word addresses in mem-slot (defconstant lambda-share-iopb-structure #o520) ; see qcom (defconstant debug-program-share-iopb-structure #o540) (defvar share-lock-prevent-accidental-recursion nil) ;(defconstant enable-locking t) (defun share-lock () (cond ((null share-lock-prevent-accidental-recursion) (setq share-lock-prevent-accidental-recursion t) ;; we don't have with-timeout yet. When we do ;; wrap the do loop with it (do () ((zerop (nubus-stuff:%bus-byte-read sharestruct-lock)))) (nubus-stuff:%bus-byte-write sharestruct-lock 1)) (t (li:error nil "share-lock called while k apparently already had lock"))) ) (defun share-unlock () (setq share-lock-prevent-accidental-recursion nil) (nubus-stuff:%bus-byte-write sharestruct-lock 0) ) (defun read-8086-multibus-address (nubus-pointer-location) (let ((multibus-address (8086-ptr-to-multibus-address (cond ((zerop (ldb (byte 2 0) nubus-pointer-location)) (nubus-stuff:%bus-quad-slot-read-unsafe (ldb (byte 8. 24.) nubus-pointer-location) (ldb (byte 24. 0) nubus-pointer-location))) (t (logior (nubus-stuff:%bus-read-byte-unsafe nubus-pointer-location) (ash (nubus-stuff:%bus-read-byte-unsafe (+ nubus-pointer-location 1)) 8.) (ash (nubus-stuff:%bus-read-byte-unsafe (+ nubus-pointer-location 2)) 16.) (ash (nubus-stuff:%bus-read-byte-unsafe (+ nubus-pointer-location 3)) 24.))))))) (values (nubus-stuff:map-multibus-address multibus-address) multibus-address)) ) (defun print-share-iopbs (&optional print-iopbs) (format t "~&sharestruct-debug-level = ~d." (nubus-stuff:%bus-byte-read sharestruct-debug-level)) (format t "~&sharestruct-lock = ~o" (nubus-stuff:%bus-byte-read sharestruct-lock)) (share-lock) ;; we do not have unwind-protect now. put it back as soon it exists ; (unwind-protect (let ((sharestruct (read-8086-multibus-address sharestruct-ptr))) (format t "~&sharestruct = ~16r" sharestruct) (cond ((zerop (ldb (byte 20. 0) sharestruct)) (li:error "~&sharestruct pointer not set up yet"))) (let ((maxiopbs (nubus-stuff:%bus-byte-read (+ sharestruct sharestruct-max-iopbs-offset ))) (currentiopb (nubus-stuff:%bus-byte-read (+ sharestruct sharestruct-current-iopb-offset)))) (format t "~&maxiopbs = ~d" maxiopbs) (format t "~¤tiopb = ~d" currentiopb) (dotimes (n maxiopbs) (let ((valid (nubus-stuff:%bus-read-byte-unsafe (+ sharestruct sharestruct-valid-table-offset (* 4 n)))) (siopb (read-8086-multibus-address (+ sharestruct sharestruct-valid-table-offset (* 4 maxiopbs) (* n 4))))) (format t "~&slot ~d: (~16r) valid = #x~16r siopb = #x~16r" n (+ sharestruct sharestruct-valid-table-offset (* 4 n)) valid siopb) (cond ((not (zerop valid)) (print-share-iopb siopb print-iopbs))))))) (share-unlock) ; ) ) (defun print-share-iopb (adr &optional print-iopbs) (format t "~&~4tshare-iopb at ~o (#x~16r)" adr adr) (format t "~&~8trunme = ~o" (nubus-stuff:%bus-read-byte-unsafe (+ adr share-iopb-runme-offset))) (format t "~&~8tslot = ~o (#x~:*~16r)" (nubus-stuff:%bus-read-byte-unsafe (+ adr share-iopb-slot-offset))) (format t "~&~8ttype = ~o" (nubus-stuff:%bus-read-byte-unsafe (+ adr share-iopb-type-offset))) (let ((iopb-address (read-8086-multibus-address (+ adr share-iopb-iopb-offset)))) (format t "~&~8tiopb = ~o ~:* ~16r" iopb-address) (if print-iopbs (print-iopb-at-nubus-address iopb-address))) (let ((inter-multi-loc (read-8086-multibus-address (+ adr share-iopb-interrupt-offset)))) (format t "~&~8tinterrupt = ~o (= nubus ~16r)" inter-multi-loc (nubus-stuff:map-multibus-address inter-multi-loc)))) (defconstant cadr-share-slot #o375) ; (cond ((= si:processor-type-code si:cadr-type-code) #o377) ; ((= si:processor-type-code si:lambda-type-code) ; (cond ((not (boundp 'si:*my-op*)) #o376) ; (t (- #o375 (si:op-proc-number si:*my-op*))))))) (defconstant cadr-share-type #o377) (defun remove-share-iopb (&optional (slot cadr-share-slot) (type cadr-share-type) (ask-p t)) (share-lock) ; (unwind-protect (let ((sharestruct (read-8086-multibus-address sharestruct-ptr))) (cond ((zerop (ldb (byte 20. 0) sharestruct)) (li:error "~&sharestruct pointer not set up yet"))) (let ((maxiopbs (nubus-stuff:%bus-byte-read (+ sharestruct sharestruct-max-iopbs-offset)))) (dotimes (n maxiopbs) (let ((valid (nubus-stuff:%bus-byte-read (+ sharestruct sharestruct-valid-table-offset (* 4 n)))) (siopb (read-8086-multibus-address (+ sharestruct sharestruct-valid-table-offset (* maxiopbs 4) (* n 4))))) (cond ((not (zerop valid)) (let ((this-slot (nubus-stuff:%bus-read-byte-unsafe (+ siopb share-iopb-slot-offset))) (this-type (nubus-stuff:%bus-read-byte-unsafe (+ siopb share-iopb-type-offset)))) (cond ((and (or (= this-slot slot) (= this-slot (logxor #xf0 slot))) (= this-type type)) (nubus-stuff:%bus-byte-write (+ sharestruct sharestruct-valid-table-offset (* n 4)) 0))) (when (not (memq (ldb (byte 4 4) this-slot) '(0 1 #xe #xf))) (print-share-iopb siopb) ; (if (if ask-p (y-or-n-p "Flush this IOPB ") ; (format t "Flushing this IOPB ") ; t) (nubus-stuff:%bus-byte-write (+ sharestruct sharestruct-valid-table-offset (* n 4)) 0))))))))) ; ) (share-unlock) ; ) ) (defun invalidate-slot (slot-number) (share-lock) (unwind-protect (let ((sharestruct (read-8086-multibus-address sharestruct-ptr))) (cond ((zerop (ldb (byte 20. 0) sharestruct)) (li:error "sharestruct not set up yet"))) (let ((maxiopbs (nubus-stuff:%bus-byte-read (+ sharestruct sharestruct-max-iopbs-offset)))) (cond ((>= slot-number maxiopbs) (li:error "there are only ~d slots" maxiopbs))) (nubus-stuff:%bus-write (+ sharestruct sharestruct-valid-table-offset (* slot-number 4)) 0))) (share-unlock))) (defun insert-share-iopb () (remove-share-iopb cadr-share-slot cadr-share-type nil) (let ((prime-memory-adr (+ (ash (cadr (car (k-memory-configuration-list))) 14.) ;;(dpb (SEND *PROC* :MEM-SLOT) (byte 4 24.) #xf0000000) (* debug-program-share-iopb-structure 4)))) (format t "~%prime-memory-adr for iopb=#x~16r" prime-memory-adr) (nubus-stuff:%bus-write (+ prime-memory-adr share-iopb-runme-offset) 0) (nubus-stuff:%bus-write (+ prime-memory-adr share-iopb-slot-offset) cadr-share-slot) (nubus-stuff:%bus-write (+ prime-memory-adr share-iopb-type-offset) cadr-share-type) ;;set up pointer from share-iopb to real iopb ;;like the old code, use 650 in virtual address space for iopb, and point ;; to it with our multibus mapping reg (nubus-stuff:write-multibus-mapping-register multibus-mapping-register-base (+ #x800000 (cadr-page-to-nubus-page 1))) (nubus-stuff:%bus-write (+ prime-memory-adr share-iopb-iopb-offset) (multibus-address-to-8086-ptr (+ (ash multibus-mapping-register-base 10.) (* #o250 4)))) ;;no interrupts (nubus-stuff:%bus-write (+ prime-memory-adr share-iopb-interrupt-offset) 0) (share-lock) (unwind-protect (let ((sharestruct (read-8086-multibus-address sharestruct-ptr))) (cond ((zerop (ldb (byte 20. 0) sharestruct)) (li:error "~&sharestruct pointer not set up yet"))) (let ((maxiopbs (nubus-stuff:%bus-byte-read (+ sharestruct sharestruct-max-iopbs-offset)))) (dotimes (n maxiopbs (li:error "out of iopb slots")) (cond ((zerop (nubus-stuff:%bus-byte-read (+ sharestruct sharestruct-valid-table-offset (* 4 n)))) (nubus-stuff:%bus-write (+ sharestruct sharestruct-valid-table-offset (* 4 maxiopbs) (* 4 n)) (multibus-address-to-8086-ptr (+ (ash multibus-mapping-register-base 10.) (* #o140 4)))) (nubus-stuff:%bus-byte-write (+ sharestruct sharestruct-valid-table-offset (* 4 n)) 1) (return nil)))))) (share-unlock)))) (defconstant multibus-interrupt-1 #xff01c1e4) (defconstant multibus-interrupt-7 #xff01c1fc) (defconstant share-trace nil) (defun share-go () (let ((prime-memory-adr (+ (dpb (k-memory-slot) (byte 8. 24.) 0) (* *physical-iopb-address* ;; debug-program-share-iopb-structure 4)))) (nubus-stuff:%bus-byte-write (+ prime-memory-adr share-iopb-runme-offset) 1) (nubus-stuff:%bus-byte-write multibus-interrupt-7 1))) (defun share-go-slot (slot-num) (share-lock) (unwind-protect (let ((sharestruct (read-8086-multibus-address sharestruct-ptr))) (format t "~&sharestruct = ~16r" sharestruct) (cond ((zerop (ldb (byte 20. 0) sharestruct)) (li:error "~&sharestruct pointer not set up yet"))) (let ((maxiopbs (nubus-stuff:%bus-byte-read (+ sharestruct sharestruct-max-iopbs-offset ))) (currentiopb (nubus-stuff:%bus-byte-read (+ sharestruct sharestruct-current-iopb-offset)))) (format t "~&maxiopbs = ~d" maxiopbs) (format t "~¤tiopb = ~d" currentiopb) (dotimes (n maxiopbs) (let ((valid (nubus-stuff:%bus-read-byte-unsafe (+ sharestruct sharestruct-valid-table-offset (* 4 n)))) (siopb (read-8086-multibus-address (+ sharestruct sharestruct-valid-table-offset (* 4 maxiopbs) (* n 4))))) (format t "~&slot ~d: (~16r) valid = #x~16r siopb = #x~16r" n (+ sharestruct sharestruct-valid-table-offset (* 4 n)) valid siopb) (cond ((not (zerop valid)) (print-share-iopb siopb t))) (cond ((and (= n slot-num) ; (yes-or-no-p "Goose this one?") t) (nubus-stuff:%bus-write-byte-unsafe (+ siopb share-iopb-runme-offset) 1))))))) (share-unlock)))