;;;-*- Mode:LISP; Package:LISP-INTERNALS; Base:10; Readtable:CL -*- ;;; ;;; Written by Youcef Bennour. ;;; (defstruct (memory-disk-paging-device (:include paging-device) (:conc-name "MPD-") (:constructor make-mpd-device)) state mem-slot quantum-bitmap (accumulated-physical-cluster-swap-list (make-array 16.)) starting-address number-of-quanta dqin-for-this-operation this-cluster cluster-count ) (defparameter *mem-slot* #Xfa) (defun initialize-memory-disk (&optional (mem-slot *mem-slot*)) (let ((device-addr (hw:dpb mem-slot (byte 8. 24) (hw:unboxed-constant 0)))) (nubus-stuff:%bus-write (hw:32+ (hw:unboxed-constant #xfff7fc) device-addr) (hw:unboxed-constant 0)) (dotimes (i #xff0) (nubus-stuff:%cluster-fill (hw:dpb-unboxed i (byte 12. 12.) device-addr) nil (hw:unboxed-constant 0))) (nubus-stuff:%bus-write (hw:32+ (hw:unboxed-constant #xfff7fc) device-addr) (hw:unboxed-constant 0)) nil)) ; (data (hw:unboxed-constant 0)) ; (inc (hw:unboxed-constant 4)) ; (limit (hw:unboxed-constant #xffefff))) ; ;; zero out control register. ; (nubus-stuff:%bus-write (hw:32+ (hw:unboxed-constant #xfff7fc) device-addr) data) ; (do ((i (hw:unboxed-constant 0) (hw:32+ i inc))) ; ((hw:32> i limit) nil) ; (nubus-stuff:%bus-write (hw:32+ i device-addr) data)) ; (nubus-stuff:%bus-write (hw:32+ (hw:unboxed-constant #xfff7fc) device-addr) data) ; ) ; ) (defun mem-disk-open (device) (unless (eq (mpd-state device) :closed) (li:error "Device ~S is already open." device)) (setf (mpd-mem-slot device) *mem-slot*) (setf (mpd-quantum-bitmap device) (array:make-1d-array 255. array:art-1b)) ;; init quantum-bitmap device. (let ((quantum-map (mpd-quantum-bitmap device))) (dotimes (i 255.) (setf (svref quantum-map i) 0))) (setf (mpd-starting-address device) 0) (setf (mpd-state device) :OPEN) ) (defun mem-disk-close (device) (unless (eq (mpd-state device) :open) (li:error "Device ~S is not open" device)) (setf (mpd-state device) :CLOSED) ) (defun mem-disk-allocate-quantum (device) (unless (eq (mpd-state device) :open) (li:error "Device ~S is not open" device)) (let ((quantum-map (mpd-quantum-bitmap device))) (dotimes (i (mpd-number-of-quanta device) (li:error "No more quanta left on Memory Disk" device)) (when (zerop (svref quantum-map i)) (setf (svref quantum-map i) 1) (return i))) ) ) (defun mem-disk-deallocate-quantum (device device-quantum-id) (unless (eq (mpd-state device) :open) (li:error "Device ~S is not open" device)) (unless (> (mpd-number-of-quanta device) device-quantum-id) (li:error "Quantum ~D does not exists for device ~S" device-quantum-id device)) (when (zerop (svref (mpd-quatum-bitmap device) device-quantum-id)) (li:error "Quantum ~D was not allocated in device ~S" device-quantum-id device)) (setf (svref (mpd-quantum-bitmap device) device-quantum-id) 0) ) (defun mem-disk-start-write-cluster (device dqin cluster-in-quantum) (unless (eq (mpd-state device) :open) (li:error "Device ~S is not open" device)) (setf (mpd-dqin-for-this-operation device) dqin) (setf (mpd-this-cluster device) cluster-in-quantum) (setf (mpd-state device) :Write-started) ) (defun mem-disk-start-read-cluster (device dqin cluster-in-quantum) (unless (eq (mpd-state device) :open) (li:error "Device ~S is not open" device)) (setf (mpd-dqin-for-this-operation device) dqin) (setf (mpd-this-cluster device) cluster-in-quantum) (setf (mpd-state device) :read-started) ) (defun mem-disk-next-cluster-to-read (device physical-cluster-number) (unless (eq (mpd-state device) :read-started) (error "A read operation has not been started for device ~S" device)) (setf (aref (mpd-accumulated-physical-cluster-swap-list device) (mpd-cluster-count device)) physical-cluster-number) (incf (mpd-cluster-count device)) ; (push physical-cluster-number (mpd-accumulated-physical-cluster-swap-list device)) ) (defun mem-disk-next-cluster-to-write (device physical-cluster-number) (unless (eq (mpd-state device) :write-started) (error "A write operation has not been started for device ~S" device)) (setf (aref (mpd-accumulated-physical-cluster-swap-list device) (mpd-cluster-count device)) physical-cluster-number) (incf (mpd-cluster-count device)) ; (push physical-cluster-number (mpd-accumulated-physical-cluster-swap-list device)) ) (defun k-mem-slot () (hw:ldb (hw:read-memory-status) hw:%%memory-status-nubus-slot-id #xF0) ) (defun mem-disk-activate-read (device) (let ((device-mem-byte-address (hw:32+ (hw:dpb-unboxed (mpd-dqin-for-this-operation device) (byte 8. 16.) (hw:unboxed-constant 0)) (hw:dpb-unboxed *mem-slot* (byte 8. 24.) (mpd-starting-address device)))) (physical-cluster-vector (mpd-accumulated-physical-cluster-swap-list device)) (cluster-size 1024.)) (do ((count 0 (1+ count)) physical-byte-address) ((= count (mpd-cluster-count device))) (setq physical-byte-address (hw:dpb-unboxed (svref physical-cluster-vector count) (byte 16. 12.) (hw:unboxed-constant 0))) (when (>= (+ count (mpd-this-cluster device)) 16.) (li:error "Cluster ran off end of quantum during mem disk read")) (setq device-mem-byte-address (hw:32+ (hw:dpb-unboxed (+ count (mpd-this-cluster device)) (byte 4. 12.) (hw:unboxed-constant 0)) device-mem-byte-address)) (nubus-stuff:%cluster-copy device-mem-byte-address nil physical-byte-address t)) ; (dotimes (i cluster-size) ; (nubus-stuff:%local-memory-write ; (hw:dpb-unboxed i (byte 10. 2.) physical-byte-address) ; (nubus-stuff:%bus-read (hw:dpb-unboxed i (byte 10. 2.) device-mem-byte-address))))) (operation-complete device))) (defun mem-disk-activate-write (device) (let ((device-mem-byte-address (hw:32+ (hw:dpb-unboxed (mpd-dqin-for-this-operation device) (byte 8. 16.) (hw:unboxed-constant 0)) (hw:dpb-unboxed *mem-slot* (byte 8. 24.) (mpd-starting-address device)))) (physical-cluster-vector (mpd-accumulated-physical-cluster-swap-list device)) (cluster-size 1024.)) (do ((count 0 (1+ count)) physical-byte-address) ((= count (mpd-cluster-count device))) (setq physical-byte-address (hw:dpb-unboxed (svref physical-cluster-vector count) (byte 16. 12.) (hw:unboxed-constant 0))) (when (>= (+ count (mpd-this-cluster device)) 16.) (li:error "Cluster ran off end of quantum during mem disk write")) (setq device-mem-byte-address (hw:32+ (hw:dpb-unboxed (+ count (mpd-this-cluster device)) (byte 4. 12.) (hw:unboxed-constant 0)) device-mem-byte-address)) (nubus-stuff:%cluster-copy physical-byte-address t device-mem-byte-address nil)) ; (dotimes (i cluster-size) ; (nubus-stuff:%bus-write ; (hw:dpb-unboxed i (byte 10. 2.) device-mem-byte-address) ; (nubus-stuff:%local-memory-read (hw:dpb-unboxed i (byte 10. 2.) physical-byte-address))))) (operation-complete device))) (defun mem-disk-operation-complete (device) (setf (mpd-dqin-for-this-operation device) nil) (setf (mpd-this-cluster device) nil) (setf (mpd-cluster-count device) 0) (setf (mpd-state device) :open) t ) (defun make-mem-disk-device () (make-mpd-device :state :closed :cluster-count 0 :dqin-for-this-operation nil :this-cluster nil :number-of-quanta 255. :opener 'mem-disk-open :closer 'mem-disk-close :quantum-allocator 'mem-disk-allocate-quantum :quantum-deallocator 'mem-disk-deallocate-quantum :reader-initializer 'mem-disk-start-read-cluster :writer-initializer 'mem-disk-start-write-cluster :next-cluster-reader 'mem-disk-next-cluster-to-read :next-cluster-writer 'mem-disk-next-cluster-to-write :reader-activate 'mem-disk-activate-read :writer-activate 'mem-disk-activate-write :operation-completer 'mem-disk-operation-complete ) ) (defun wire-down-pages (&aux pcd-data) ;; wire down existing world. (dotimes (i vinc:*physical-memory-max-clusters*) (setq pcd-data (pcd:read-pcd i)) (unless (eq (pcd:pcd-status pcd-data) pcd:$$status-invalid) (pcd:write-pcd i (setf (pcd:pcd-status pcd-data) pcd:$$status-wired)))) ) (defun set-all-paging-device-numbers (number) (dotimes (q 4096.) (quantum-map:modify-quantum-map q #'(lambda (data) (hw:dpb number quantum-map:%%quantum-map-device data))))) (defun paging-device-open? (device) (eq (mpd-state device) :open) ) ;;;; Test functions. (defvar *paging-device* nil) (defvar *big-array* nil) (defun set-up-paging-stuff () (setq gr:*findcore-pointer* 0) ;;; Just until PCD-TABLE gets recompiled (boot-stack-groups) (or *paging-devices* (setq *paging-devices* (make-paging-devices))) (setq *paging-device* (make-mem-disk-device)) (open-paging-device *paging-device*) (setf (svref *paging-devices* *page-band-paging-device-id*) *paging-device*) (set-all-paging-device-numbers 2) (error "Set dev numbers") (wire-down-pages) (error "Wired pages") ;; init mem disk (initialize-memory-disk) (error "Inited mem disk") ;; allocate a monstruous array that will not fit in core. (setq *big-array* (array:make-array '(2000. 1024.) :element-type t)) (loop) ) (defun force-paging () (loop (let ((a *big-array*) v) (dotimes (i 2000.) (dotimes (j 1024.) (setf (aref a i j) i))) (error "Wrote *big-array*") (dotimes (i 2000.) (dotimes (j 1024.) (unless (= i (aref a i j)) (error "Bad data reading *big-array*" i j (aref a i j))))) (error "Read *big-array*") (setq v (array:array-element-type a)))) (loop))