;;; -*- Mode:LISP; Package:NF; Base:8; Readtable:ZL -*- ;;; 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 (defconst sharestruct-ptr #xff000080) (defconst sharestruct-lock #xff000084) (defconst sharestruct-debug-level #xff000085) (defconst sharestruct-share-lock 0) (defconst sharestruct-max-iopbs-offset 4) (defconst sharestruct-current-iopb-offset 8) (defconst sharestruct-valid-table-offset 12.) (defconst share-iopb-runme-offset 0) (defconst share-iopb-slot-offset 4) (defconst share-iopb-type-offset 8) (defconst share-iopb-iopb-offset 12.) (defconst share-iopb-interrupt-offset 16.) (defun %nubus-read-unalinged (nubus-adr) (let ((quad-slot (ldb (byte 8 24.) nubus-adr)) (offset (ldb (byte 24. 0) nubus-adr))) (let ((b0 (si:%nubus-read-8 quad-slot offset)) (b1 (si:%nubus-read-8 quad-slot (+ offset 1))) (b2 (si:%nubus-read-8 quad-slot (+ offset 2))) (b3 (si:%nubus-read-8 quad-slot (+ offset 3)))) (dpb b3 (byte 8 24.) (dpb b2 (byte 8 16.) (dpb b1 (byte 8 8) b0)))))) (defun %read-nubus-adr-8 (nubus-adr) (si:%nubus-read-8 (ldb (byte 8 24.) nubus-adr) (ldb (byte 24. 0) nubus-adr))) (defun %write-nubus-adr-8 (nubus-adr data) (si:%nubus-write-8 (ldb (byte 8 24.) nubus-adr) (ldb (byte 24. 0) nubus-adr) data)) (defun %read-nubus-adr (nubus-adr) (si:%nubus-read (ldb (byte 8 24.) nubus-adr) (ldb (byte 24. 0) nubus-adr))) (defun read-8086-multibus-address (nubus-adr) (let ((multibus-address (8086-ptr-to-multibus-address (%nubus-read-unalinged nubus-adr)))) (values (map-multibus-address multibus-address) multibus-address))) (defun map-multibus-address (nubus-address) "return nubus-address, unless it points to the multibus, and is mapped to the nubus. in that case, follow the mapping, and return that address" (cond ((not (= (ldb (byte 8 24.) nubus-address) #xff)) nubus-address) (t (let ((map-to (si:read-multibus-mapping-register (ldb (byte 10. 10.) nubus-address)))) (cond ((ldb-test (byte 1 23.) map-to) ; check valid bit (dpb (ldb (byte 22. 0) map-to) (byte 22. 10.) (ldb (byte 10. 0) nubus-address))) (t nubus-address)))))) (defun print-share-iopbs (&optional print-iopbs) (let ((sharestruct (read-8086-multibus-address sharestruct-ptr))) (format t "~&sharestruct = ~16r" sharestruct) (let ((maxiopbs (%read-nubus-adr-8 (+ sharestruct sharestruct-max-iopbs-offset))) (currentiopb (%read-nubus-adr-8 (+ sharestruct sharestruct-current-iopb-offset)))) (format t "~&maxiopbs = ~d" maxiopbs) (format t "~¤tiopb = ~d" currentiopb) (dotimes (n maxiopbs) (let ((valid (%read-nubus-adr-8 (+ 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) (when (not (zerop valid)) (print-share-iopb siopb print-iopbs))))))) (defun print-share-iopb (adr &optional print-iopbs) (format t "~&~4tshare-iopb at ~o (#x~16r)" adr adr) (format t "~&~8trunme = ~o" (%read-nubus-adr-8 (+ adr share-iopb-runme-offset))) (format t "~&~8tslot = ~o (#x~:*~16r)" (%read-nubus-adr-8 (+ adr share-iopb-slot-offset))) (format t "~&~8ttype = ~o" (%read-nubus-adr-8 (+ 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 (map-multibus-address inter-multi-loc)))) (defun remove-share-iopb (slot type) (let ((sharestruct (read-8086-multibus-address sharestruct-ptr))) (let ((maxiopbs (%read-nubus-adr-8 (+ sharestruct sharestruct-max-iopbs-offset)))) (dotimes (n maxiopbs) (let ((valid (%read-nubus-adr-8 (+ 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 (%read-nubus-adr-8 (+ siopb share-iopb-slot-offset))) (this-type (%read-nubus-adr-8 (+ siopb share-iopb-type-offset)))) (cond ((and (or (= this-slot slot) (= this-slot (logxor #xf0 slot))) (= this-type type)) (%write-nubus-adr-8 (+ sharestruct sharestruct-valid-table-offset (* n 4)) 0))))))))))) (defstruct (share-iopb (:type :named-array) (:constructor nil) (:print "#<~S Slot #x~x Type #x~x ~S>" (type-of share-iopb) (share-iopb-slot share-iopb) (share-iopb-type share-iopb) (%pointer share-iopb))) share-iopb-runme share-iopb-slot share-iopb-type share-iopb-iopb share-iopb-interrupt) (defun get-share-iopb () (let ((share-iopb (allocate-resource 'si:dma-buffer 1))) (array-initialize share-iopb 0) (setf (array-leader share-iopb 1) 'share-iopb) share-iopb)) (defstruct (interphase-iopb (:type :named-array) (:constructor nil) (:print "#<~S ~S>" (type-of interphase-iopb) (%pointer interphase-iopb))) interphase-iopb-command interphase-iopb-options interphase-iopb-status interphase-iopb-errors interphase-iopb-unit interphase-iopb-head interphase-iopb-cylinder-hi interphase-iopb-cylinder-lo interphase-iopb-sector-hi interphase-iopb-sector-lo interphase-iopb-count-hi interphase-iopb-count-lo interphase-iopb-dma-count interphase-iopb-buffer-hi interphase-iopb-buffer-med interphase-iopb-buffer-lo interphase-iopb-base-reg-hi interphase-iopb-base-reg-lo interphase-iopb-rel-adr-hi interphase-iopb-rel-adr-lo interphase-iopb-reserved interphase-iopb-linked-iopb-hi interphase-iopb-linked-iopb-med interphase-iopb-linked-iopb-lo ) (defun get-interphase-iopb () (let* ((dma-buffer (allocate-resource 'si:dma-buffer 1)) (iopb (si:dma-buffer-8b dma-buffer))) (array-initialize iopb 0) (setf (array-leader iopb 1) 'interphase-iopb) iopb)) (defun insert-share-iopb (slot type) (remove-share-iopb slot type) (let* ((share-iopb (get-share-iopb)) (phys-adr (si:vadr-to-nubus-phys (%pointer-plus share-iopb (si:array-data-offset share-iopb))))) (array-initialize share-iopb 0) (setf (share-iopb-slot share-iopb) slot) (setf (share-iopb-type share-iopb) 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 (write-multibus-mapping-register lam-multibus-mapping-register-base (+ 1_23. (cadr-page-to-nubus-page 1))) (send *proc* :bus-write (+ prime-memory-adr share-iopb-iopb-offset) (multibus-address-to-8086-ptr (+ (ash lam-multibus-mapping-register-base 10.) (* 250 4)))) ;;no interrupts (send *proc* :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)) (ferror nil "~&sharestruct pointer not set up yet"))) (let ((maxiopbs (send *proc* :bus-read-byte (+ sharestruct sharestruct-max-iopbs-offset)))) (dotimes (n maxiopbs (ferror nil "out of iopb slots")) (cond ((zerop (send *proc* :bus-read-byte (+ sharestruct sharestruct-valid-table-offset (* 4 n)))) (send *proc* :bus-write (+ sharestruct sharestruct-valid-table-offset (* 4 maxiopbs) (* 4 n)) (multibus-address-to-8086-ptr (+ (ash lam-multibus-mapping-register-base 10.) (* 140 4)))) (send *proc* :bus-write-byte (+ sharestruct sharestruct-valid-table-offset (* 4 n)) 1) (return nil)))))) (share-unlock)))) (defconst multibus-interrupt-7 #xff01c1fc) (defun share-go () (let ((prime-memory-adr (+ (ash (cadr (car (send *proc* :memory-configuration-list))) 10.) ;(dpb (SEND *PROC* :MEM-SLOT) (byte 4 24.) #xf0000000) (* debug-program-share-iopb-structure 4)))) (send *proc* :bus-write-byte (+ prime-memory-adr share-iopb-runme-offset) 1) (send *proc* :bus-write-byte multibus-interrupt-7 1)))