;;; -*- Mode:LISP; Package:VIRTUAL-MEMORY; Base:10; Readtable:CL -*- (in-package 'virtual-memory) (export '( *temporary-map-entry* $$read-cdr $$read-no-cdr associate-temporary deassociate-temporary boot-allocate-physical-clusters md-start-write-generic system-table-ref system-table-store vma-start-read-generic write-md-generic write-vma-generic )) ;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Virtual memory SYSTEM ;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;; ;;; SYSTEM TABLES ;;;;;;;;;;;;;;;;;; (defun system-table-ref (table index) (hw:vma-start-read-no-transport (hw:24+ table index) :unboxed :unboxed) (hw:read-md)) (defun system-table-store (table index new-value) (hw:write-vma-unboxed (hw:24+ table index)) (hw:md-start-write-no-gc-trap new-value :unboxed)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Physical cluster free pointer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; At boot time, the PCD table doesn't exist, so we cannot ;;; just call findcore. Instead, we use this free pointer ;;; and hope that we don't fall off the end of memory before ;;; we can findcore. Called only by pcd:create-physical-cluster-data-table. (defun boot-allocate-physical-clusters (how-many) (trap::without-traps #'(lambda () (prog1 gr::*physical-cluster-free-pointer* (incf gr::*physical-cluster-free-pointer* how-many))))) ;;;;;;;;;;;;;;;;;;;;;;;; ;;; Temporary map entry ;;;;;;;;;;;;;;;;;;;;;;;; ;;; The temporary map entry is set up to never fault. ;;; It is used to trample on write only clusters, etc. ;;; Should think about making this atomic someday. ;;; For now, just ignore it and deal with it on an ;;; ad hoc basis. (defconstant *temporary-map-entry* 1.) (defun associate-temporary (virtual-cluster physical-cluster volatility) (hw:read-md) ;wait for mem (if (= gr:*temporary-map-entry-virtual-cluster* -1) (setq gr::*temporary-map-entry-virtual-cluster* virtual-cluster) (trap::illop "Recursive use of temporary map entry")) (map:associate-local-memory physical-cluster *temporary-map-entry* map:$$map-status-normal) (map:write-cluster-volatility *temporary-map-entry* volatility)) (defun deassociate-temporary () (hw:read-md) ;wait for mem (map::write-map-status *temporary-map-entry* map:$$map-status-direct-mapped) (setq gr:*temporary-map-entry-virtual-cluster* -1)) ;(defun initialize-fresh-cluster (physical-cluster virtual-cluster) ; (associate-temporary physical-cluster) ; (labels ((zap-cluster (temporary-address virtual-address count) ; (if (zerop count) ; () ; (progn (hw:write-md-unboxed virtual-address) ; (hw:vma-start-write-unboxed-no-gc-trap temporary-address) ; (zap-cluster (1+ temporary-address) ; (1+ virtual-address) ; (1- count)))))) ; (zap-cluster (cluster->address gr::*temporary-map-entry*) ; (cluster->address virtual-cluster) ; vinc:*qs-in-cluster*))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Generic memory instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Of course all of these should be called ;;; from compiled code only. (defun write-md-generic (md boxed) (if (= boxed hw:$$boxed) (hw:write-md-boxed md) (hw:write-md-unboxed md))) (defun md-start-write-generic (md md-boxed gc-write-test) (if (= md-boxed hw:$$boxed) (if (= gc-write-test vinc:$$gc-write-test) (hw:md-start-write-boxed md) (hw:md-start-write-no-gc-trap-boxed md)) (if (= gc-write-test vinc:$$gc-write-test) (hw:md-start-write-unboxed md) (hw:md-start-write-no-gc-trap-unboxed md)))) (defun write-vma-generic (vma vma-boxed) (if (= vma-boxed hw:$$boxed) (hw:write-vma-boxed vma) (hw:write-vma-unboxed vma))) (defun vma-start-write-generic (vma vma-boxed gc-trap) (if (= vma-boxed hw:$$boxed) (if (= gc-trap vinc:$$gc-write-test) (hw:vma-start-write-boxed vma) (hw:vma-start-write-no-gc-trap-boxed vma)) (if (= gc-trap vinc:$$gc-write-test) (hw:vma-start-write-unboxed vma) (hw:vma-start-write-no-gc-trap-unboxed vma)))) (defconstant $$read-no-cdr 0) (defconstant $$read-cdr 1) (defun vma-start-read-generic (vma-boxed md-boxed cdr trans-type location) (if (= vma-boxed hw:$$boxed) (if (= md-boxed hw:$$boxed) (if (= cdr $$read-no-cdr) (cond ((= trans-type vinc:$$transport-type-transport) (hw:vma-start-read location :boxed :boxed)) ((= trans-type vinc:$$transport-type-no-transport) (hw:vma-start-read-no-transport location :boxed :boxed)) ((= trans-type vinc:$$transport-type-visible-evcp) (hw:vma-start-read-visible-evcp location :boxed :boxed)) ((= trans-type vinc:$$transport-type-write) (hw:vma-start-read-will-write location :boxed :boxed))) (cond ((= trans-type vinc:$$transport-type-transport) (hw:vma-start-read-cdr location :boxed :boxed)) ((= trans-type vinc:$$transport-type-no-transport) (hw:vma-start-read-cdr-no-transport location :boxed :boxed)) ((= trans-type vinc:$$transport-type-visible-evcp) (hw:vma-start-read-cdr-visible-evcp location :boxed :boxed)) ((= trans-type vinc:$$transport-type-write) (hw:vma-start-read-cdr-will-write location :boxed :boxed)))) (if (= cdr $$read-no-cdr) (cond ((= trans-type vinc:$$transport-type-transport) (hw:vma-start-read location :boxed :unboxed)) ((= trans-type vinc:$$transport-type-no-transport) (hw:vma-start-read-no-transport location :boxed :unboxed)) ((= trans-type vinc:$$transport-type-visible-evcp) (hw:vma-start-read-visible-evcp location :boxed :unboxed)) ((= trans-type vinc:$$transport-type-write) (hw:vma-start-read-will-write location :boxed :unboxed))) (cond ((= trans-type vinc:$$transport-type-transport) (hw:vma-start-read-cdr location :boxed :unboxed)) ((= trans-type vinc:$$transport-type-no-transport) (hw:vma-start-read-cdr-no-transport location :boxed :unboxed)) ((= trans-type vinc:$$transport-type-visible-evcp) (hw:vma-start-read-cdr-visible-evcp location :boxed :unboxed)) ((= trans-type vinc:$$transport-type-write) (hw:vma-start-read-cdr-will-write location :boxed :unboxed))))) (if (= md-boxed hw:$$boxed) (if (= cdr $$read-no-cdr) (cond ((= trans-type vinc:$$transport-type-transport) (hw:vma-start-read location :unboxed :boxed)) ((= trans-type vinc:$$transport-type-no-transport) (hw:vma-start-read-no-transport location :unboxed :boxed)) ((= trans-type vinc:$$transport-type-visible-evcp) (hw:vma-start-read-visible-evcp location :unboxed :boxed)) ((= trans-type vinc:$$transport-type-write) (hw:vma-start-read-will-write location :unboxed :boxed))) (cond ((= trans-type vinc:$$transport-type-transport) (hw:vma-start-read-cdr location :unboxed :boxed)) ((= trans-type vinc:$$transport-type-no-transport) (hw:vma-start-read-cdr-no-transport location :unboxed :boxed)) ((= trans-type vinc:$$transport-type-visible-evcp) (hw:vma-start-read-cdr-visible-evcp location :unboxed :boxed)) ((= trans-type vinc:$$transport-type-write) (hw:vma-start-read-cdr-will-write location :unboxed :boxed)))) (if (= cdr $$read-no-cdr) (cond ((= trans-type vinc:$$transport-type-transport) (hw:vma-start-read location :unboxed :unboxed)) ((= trans-type vinc:$$transport-type-no-transport) (hw:vma-start-read-no-transport location :unboxed :unboxed)) ((= trans-type vinc:$$transport-type-visible-evcp) (hw:vma-start-read-visible-evcp location :unboxed :unboxed)) ((= trans-type vinc:$$transport-type-write) (hw:vma-start-read-will-write location :unboxed :unboxed))) (cond ((= trans-type vinc:$$transport-type-transport) (hw:vma-start-read-cdr location :unboxed :unboxed)) ((= trans-type vinc:$$transport-type-no-transport) (hw:vma-start-read-cdr-no-transport location :unboxed :unboxed)) ((= trans-type vinc:$$transport-type-visible-evcp) (hw:vma-start-read-cdr-visible-evcp location :unboxed :unboxed)) ((= trans-type vinc:$$transport-type-write) (hw:vma-start-read-cdr-will-write location :unboxed :unboxed)))))))