;;; -*- Mode:LISP; Package:(COLD :use (K LISP)); Readtable:CL; Base:10 -*- ;;;; Cold Loader ;;; Builds a Cold Load (defparameter *cold-files* '("jb:k;trap.kbin" "jb:k;nuclear-control.kbin" "jb:k;gc-ram.kbin" "jb:k;datatype-ram.kbin" "jb:k;memory-map.kbin" "jb:k;vmem.kbin" "jb:k;transporter-ram.kbin" "jb:k;timers.kbin" "jb:k;pcd-table.kbin" "jb:k;quantum-map.kbin" "jb:k;map-fault.kbin" "jb:k;memory-management.kbin" "jb:k;region-bits.kbin" "jb:k;region-data.kbin" "jb:k;gc-fault.kbin" "jb:k;cons.kbin" "jb:k;area-data.kbin" "jb:k;nubus-interrupts.kbin" "jb:k.array;array.kbin" "jb:k;symbols.kbin" "jb:kbug2;common-definitions.kbin" "jb:kbug2;streams.kbin" "jb:kbug2;k2.kbin" "jb:k;warm-loader.kbin" "jb:k;boot.kbin")) (defconstant *cold-data-size* (ash 77. 10.) "Size of cold load data space in words") (defconstant *cold-data* (make-array (ash *cold-data-size* 2) :element-type '(unsigned-byte 16.))) (defconstant *cold-code-size* (ash 16 10.) "Size of cold load code space in words") (defconstant *cold-code* (make-array (ash *cold-code-size* 2) :element-type '(unsigned-byte 16.))) (defconstant cold-code-start 0) (defvar *cold-code-pointer* cold-code-start) (defvar *cold-loaded-functions* '()) (defmacro cold-data-read (address) `(let ((.address. (ash ,address 1))) (logior (aref *cold-data* .address.) (ash (aref *cold-data* (1+ .address.)) 16.)))) (defmacro cold-data-write (address data) `(let ((.address. (ash ,address 1)) (.data. ,data)) (setf (aref *cold-data* .address.) (logand .data. #xFFFF)) (setf (aref *cold-data* (1+ .address.)) (ash .data. -16.)))) (defun cold-code-read (code-address) (let ((address (ash code-address 2))) (logior (aref *cold-code* address) (ash (aref *cold-code* (+ address 1)) 16.) (ash (aref *cold-code* (+ address 2)) 32.) (ash (aref *cold-code* (+ address 3)) 48.)))) (defun cold-code-write (code-address data) (let ((address (ash code-address 2))) (setf (aref *cold-code* address) (ldb (byte 16. 0) data)) (setf (aref *cold-code* (+ 1 address)) (ldb (byte 16. 16.) data)) (setf (aref *cold-code* (+ 2 address)) (ldb (byte 16. 32.) data)) (setf (aref *cold-code* (+ 3 address)) (ldb (byte 16. 48.) data)))) ;;;; Cold Load Initial Code (defvar *cold-files-loaded* '()) (defun same-file-except-for-version (file1 file2) (eq (zl:send file1 :generic-pathname) (zl:send file2 :generic-pathname))) (defun cold-file-needs-loading? (file) (not (member file *cold-files-loaded*))) (defun record-cold-file-loaded (pathname) (setq *cold-files-loaded* (cons pathname (delete pathname *cold-files-loaded* :test #'same-file-except-for-version)))) (defvar *cold-functions-loaded* '()) (defun make-cold-function-entry (compiled-function-structure source-file code) (list compiled-function-structure source-file code)) (defsetf cold-function-entry-structure (entry) (new-value) `(setf (first ,entry) ,new-value)) (defun cold-function-entry-source-file (entry) (second entry)) (defsetf cold-function-entry-source-file (entry) (new-value) `(setf (second ,entry) ,new-value)) (defsetf cold-function-entry-code (entry) (new-value) `(setf (third ,entry) ,new-value)) (defun enter-compiled-function (structure source-file code) (let ((entry (assoc structure *cold-functions-loaded* :test #'(lambda (s1 s2) (eq (nc::ncompiled-function-name s1) (nc::ncompiled-function-name s2)))))) (if (null entry) (setq *cold-functions-loaded* (append *cold-functions-loaded* (list (make-cold-function-entry structure source-file code)))) (progn (setf (cold-function-entry-structure entry) structure) (setf (cold-function-entry-source-file entry) source-file) (setf (cold-function-entry-code entry) code))))) (zl:defsubst cold-read (stream) (read stream)) (zl:defsubst cold-read-byte (stream) (read-byte stream)) (defun cold-read-instruction (stream) (let ((i (logior (ash (cold-read-byte stream) 0.) (ash (cold-read-byte stream) 8.) (ash (cold-read-byte stream) 16.) (ash (cold-read-byte stream) 24.) (ash (cold-read-byte stream) 32.) (ash (cold-read-byte stream) 40.) (ash (cold-read-byte stream) 48.) (ash (cold-read-byte stream) 56.)))) ; (format t "~%~s" (nc::dis i)) i)) (defun cold-load-code (stream) (let ((size-in-instructions (cold-read stream))) (do ((count size-in-instructions (1- count)) (instructions '() (cons (cold-read-instruction stream) instructions))) ((zerop count) (reverse instructions))))) (defun create-cold-compiled-function (name local-refs refs immediates length) (let ((fcn (nc::make-ncompiled-function :name name :starting-address nil :local-refs local-refs :refs refs :immediates immediates :length length :code :in-cold-load))) (push fcn *cold-loaded-functions*) (setf (nc::nsymbol-function name) fcn))) (defun find-named-function (name) (find name *cold-loaded-functions* :key #'nc::ncompiled-function-name)) (defun cold-disassemble (fcn) (format t "~&In cold load:") (if (symbolp fcn) (setq fcn (nc::get-ncompiled-function fcn))) (let ((sa (nc::ncompiled-function-starting-address fcn))) (let ((*print-base* 16.)) (format t "~&~x:" sa) (do ((addr sa (1+ addr)) (n (nc::ncompiled-function-length fcn) (1- n))) ((zerop n)) (format t "~& ~a" (nc::dis (cold-code-read addr)))))) fcn) (defvar *cold-fasl-op-handler-table* (make-array nc::n-fasl-ops)) (defmacro define-cold-fasl-op-handler (name lambda-list &body body) (let ((fname (gensym name))) `(progn (defun ,fname ,lambda-list ,@body) (setf (aref *cold-fasl-op-handler-table* ,name) #',fname)))) (defun cold-fasload (filename &key (package *package*)) (let ((nc::*fasl-op-handler-table* *cold-fasl-op-handler-table*)) (nc::nfasload filename :package package))) (define-cold-fasl-op-handler NC::FASL-OP/DEFUN (stream) (let ((name (cold-read stream)) (lambda-list (cold-read stream)) (local-refs (cold-read stream)) (refs (cold-read stream)) (immediates (cold-read stream)) (code (cold-load-code stream))) lambda-list (enter-compiled-function (create-cold-compiled-function name local-refs refs immediates (length code)) (zl:send stream :pathname) code))) ;;; This doesn't install the macro (define-cold-fasl-op-handler NC::FASL-OP/MACRO (stream) (let ((name (cold-read stream)) (lambda-list (cold-read stream)) (local-refs (cold-read stream)) (refs (cold-read stream)) (immediates (cold-read stream)) (code (cold-load-code stream))) name lambda-list local-refs refs immediates code nil)) ; (create-cold-compiled-function name code local-refs refs immediates))) ;;; More here too (define-cold-fasl-op-handler NC::FASL-OP/SUBST (stream) (let ((name (cold-read stream)) (lambda-list (cold-read stream)) (body (cold-read stream)) (local-refs (cold-read stream)) (refs (cold-read stream)) (immediates (cold-read stream)) (code (cold-load-code stream))) lambda-list body (enter-compiled-function (create-cold-compiled-function name local-refs refs immediates (length code)) (zl:send stream :pathname) code))) (define-cold-fasl-op-handler NC::FASL-OP/EVAL (stream) (let ((form (cold-read stream))) (case (car form) ;((in-package export) (eval form)) ((defconstant)) (t (format t "~&~s wants to be evaluated" form))))) (defun cold-link (cfun) "Relocate and resolve references of FUNCTION" (let ((starting-address (nc::ncompiled-function-starting-address cfun))) ;; Link local ref addresses (dolist (local-ref (nc::ncompiled-function-local-refs cfun)) (let ((iaddr (+ starting-address (car local-ref))) (toffset (cdr local-ref))) (cold-code-write iaddr (if (not (minusp toffset)) (dpb (ldb (byte (byte-size hw:%%i-branch-address) 0) (+ starting-address toffset)) hw:%%i-branch-address (cold-code-read iaddr)) ;; negative offset means pc ref (imm32) (dpb vinc:$$dtp-code vinc:%%data-type (logior (- starting-address toffset) (logand #xFFFFFFFFFF000000 (cold-code-read iaddr)))))))) ;; Link Refs (dolist (ref (nc::ncompiled-function-refs cfun)) (let ((reffun (find-named-function (if (symbolp (cdr ref)) (cdr ref) (second ref)))) ;(nargs (third ref)) ) (if reffun (let ((ref-addr (+ starting-address (car ref)))) (cold-code-write ref-addr (logior (logand #xFFFFFFFFFF000000 (cold-code-read ref-addr)) (nc::ncompiled-function-starting-address reffun))) (pushnew (cons cfun (car ref)) (nc::ncompiled-function-callees reffun) :test #'equal)) (format t "~&~S is undefined in ~s" (cdr ref) (nc::ncompiled-function-name cfun))))) ;; Do immediates (if (nc::ncompiled-function-immediates cfun) (format t "~&Immediates used in ~s: ~s" (nc::ncompiled-function-name cfun) (nc::ncompiled-function-immediates cfun))) )) (defun link-cold-loaded-functions () (dolist (f *cold-loaded-functions*) (cold-link f))) (defun cold-load-files (files) (dolist (file files) (let ((real-file (zl:probef file))) (when (cold-file-needs-loading? real-file) (forget-functions-in-file real-file) (cold-fasload real-file) (record-cold-file-loaded real-file)))) (cold-load-functions) (link-cold-loaded-functions)) (defun cold-load-functions () (setq *cold-code-pointer* cold-code-start) (setq *cold-loaded-functions* '()) (dolist (function *cold-functions-loaded*) (let* ((descriptor (first function)) (code (third function)) (next-block (dpb 0 (byte 12. 0.) (+ *cold-code-pointer* (dpb 1. (byte 1. 12.) 0.)))) (size-in-instructions (nc::ncompiled-function-length descriptor))) (when (> (+ size-in-instructions *cold-code-pointer*) next-block) (setq *cold-code-pointer* next-block)) (setf (nc::ncompiled-function-starting-address descriptor) *cold-code-pointer*) (dolist (instruction code) (cold-code-write *cold-code-pointer* instruction) (incf *cold-code-pointer*)) (push descriptor *cold-loaded-functions*)))) (defun forget-functions-in-file (file) (setq *cold-functions-loaded* (remove-if #'(lambda (source-file) (same-file-except-for-version source-file file)) *cold-functions-loaded* :key #'cold-function-entry-source-file))) ;;;; Cold Load Initial Data (defmacro dpb-multiple (&rest fields) (labels ((expander (fields) (cond ((null fields) (error "Even number of arguments to ~s" 'dpb-multiple)) ((null (rest fields)) (first fields)) (t `(DPB ,(first fields) ,(second fields) ,(expander (rest (rest fields)))))))) (expander fields))) (defun cluster->address (cluster) (dpb cluster vinc::%%cluster-number 0)) ;;; Physical locations of the initial data. ;;; NIL is at virtual address 0 ;;; The Boot vector is an art-32b whose data begins at *boot-vector-origin* ;;; in the middle of cluster 0. The cold load builder ;;; will place a header of the appropriate type before it. (defparameter *boot-vector-origin* 42.) ;absolute. ;;; The physical cluster table will go in quantum 1. ;;; It takes up half of a quantum. ;;; In the second half of the quantum, we put ;;; the quantum map and the region bits. Each of ;;; these takes up a quater of the quantum. ;;; Cluster addresses (defparameter *initial-map-data-physical-location* (cluster->address 2.)) ;64 clusters (defparameter *quantum-map-physical-location* 66.) (defparameter *quantum-map-clusters* 4.) (defparameter *region-bits-physical-location* 70.) (defparameter *region-bits-clusters* 4.) (defparameter *initial-physical-cluster-data-physical-location* 74.) ;1 cluster (defparameter *initial-gc-ram-data-physical-location* (cluster->address 75.)) ;1 cluster (defparameter *initial-transporter-ram-data-physical-location* 76.) ;;; Virtual addresses of nifty things. ;;; Quantum 0. ;;; Cluster 1. (defparameter *temporary-map-entry-location* (ash 1. (byte-position vinc::%%cluster-number))) ;;; Quantum 1. ;;; Clusters 0. 7. (defparameter *physical-cluster-table-location* (* 1 (ash 1 (byte-position vinc::%%quantum-number)))) ;;; Clusters 8. 11. (defparameter *quantum-map-virtual-location* (+ *physical-cluster-table-location* (ash 1. (1- (byte-position vinc::%%quantum-number))))) ;;; Clusters 12. 15. (defparameter *region-bits-virtual-location* (+ *quantum-map-virtual-location* (ash 1 (- (byte-position vinc::%%quantum-number) 2)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Initial map cluster data ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun load-initial-map-data () ;; Make everything volatility 0. (dotimes (i map::*number-of-map-entries*) (cold-data-write (+ i *initial-map-data-physical-location*) (dpb-multiple 0. hw:%%map-volatility map::$$cluster-fresh map::%%map-fresh-cluster 0.))) ;; Cluster 0 is volatility 1. (cold-data-write *initial-map-data-physical-location* (dpb-multiple 1. hw:%%map-volatility map::$$cluster-not-fresh map::%%map-fresh-cluster 0.))) ;;; We will move this comment down later. ;(defparameter *boot-quanta* ; (list ; (list 0. *null-paging-device* 0) ; (list 1. *null-paging-device* 1))) ;(defun load-boot-quantum-map () ; (do ((devices (reverse *quantum-devices*) (if devices (rest devices) nil)) ; (devnum 0 (1+ devnum))) ; ((or (null devices) (= devnum 16.)) ; (when devices ; (error "Too many quantum devices"))) ; (setf (aref *quantum-device-vector* devnum) ; (if devices ; (first devices) ; *null-paging-device* ; ))) ; ;; Zero all quanta. ; (dotimes (i *number-of-quanta*) ; (cold-data-write ; (+ i (cluster->address *quantum-map-physical-location*)) ; 0.)) ; ;; Write initial quanta. ; (dolist (q *boot-quanta*) ; (cold-data-write ; (+ (first q) (cluster->address *quantum-map-physical-location*)) ; (dpb-multiple-unboxed ; (find-position-in-list (second q) *quantum-devices*) ; quantum-map::%%quantum-map-device ; (third q) quantum-map::%%quantum-map-region-origin ; quantum-map::$$quantum-mapped quantum-map::%%Quantum-map-status ; 0.)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Initial physical cluster data ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun get-initial-physical-cluster-data () (list ;; Map in the wired instructions. (list (vinc:cluster-number *cold-data-size*) (vinc:cluster->address hw:*first-instruction-cluster*) pcd::$$init-map-wired-read-only (1+ (vinc:cluster-number (ash *cold-code-pointer* 2)))) (list *quantum-map-physical-location* *quantum-map-virtual-location* pcd::$$init-map-wired *quantum-map-clusters*) (list *region-bits-physical-location* *region-bits-virtual-location* pcd::$$init-map-wired *region-bits-clusters*) ;; Shared memory cluster (list 2. (cluster->address 2.) pcd::$$init-map-wired 1.) ;; This must be last. It maps NIL. (list 0. 0. pcd::$$init-map-wired 1.))) ;;;; This function fakes up the initial physical cluster data. (defun load-initial-physical-cluster-data () (let ((pointer (1- *initial-physical-cluster-data-physical-location*))) (dolist (record (get-initial-physical-cluster-data)) (cold-data-write (incf pointer) (first record)) (cold-data-write (incf pointer) (vinc:cluster-number (second record))) (cold-data-write (incf pointer) (third record)) (cold-data-write (incf pointer) (fourth record))))) (defun get-boot-gc-ram-data () (list ;; quantum, volatility, oldspace ;; Resident symbols (list 0. 0. hw:$$not-oldspace) ;; Paging tables (list 1. 0. hw:$$not-oldspace))) (defun load-boot-gc-ram-data () (dotimes (i gc-ram::*number-of-gc-ram-entries*) (cold-data-write (+ i *initial-gc-ram-data-physical-location*) (dpb-multiple 0. hw:%%gc-ram-quantum-volatility hw:$$not-oldspace hw:%%gc-ram-quantum-oldspace 0.))) (dolist (record (get-boot-gc-ram-data)) (cold-data-write (+ (first record) *initial-gc-ram-data-physical-location*) (dpb-multiple (second record) hw:%%gc-ram-quantum-volatility (third record) hw:%%gc-ram-quantum-oldspace 0.)))) ;;; This function has a corresponding reader in "TRANSPORTER-RAM" (defun modify-boot-transporter-ram-data (mode type datatype vma-boxed md-boxed modifier) (let ((address (+ (cluster->address *initial-transporter-ram-data-physical-location*) (dpb-multiple datatype (byte (byte-size hw:%%transporter-ram-md-byte) 0.) type (byte (byte-size hw:%%memory-status-transport-type) (byte-size hw:%%transporter-ram-md-byte)) mode (byte (byte-size hw:%%memory-control-transporter-mode) (+ (byte-size hw:%%memory-status-transport-type) (byte-size hw:%%transporter-ram-md-byte))) 0.))) (byte-offset (byte 4. (dpb-multiple vma-boxed (byte 1. 2.) md-boxed (byte 1. 3.) 0)))) (let ((data-there (cold-data-read address))) (let ((new-data (funcall modifier (ldb byte-offset data-there)))) (cold-data-write address (dpb new-data byte-offset data-there)))))) (defun expand-data-modifier (bit-list) (labels ((convert-to-ones (bit) (if (null bit) 1 bit)) (convert-to-zeros (bit) (if (null bit) 0 bit)) (compact-bits (bit-list) (compact-iter bit-list 0)) (compact-iter (bit-list answer) (if (null bit-list) answer (compact-iter (rest bit-list) (+ (ash answer 1.) (first bit-list))))) ) (let ((and-pattern (compact-bits (mapcar #'convert-to-ones bit-list))) (ior-pattern (compact-bits (mapcar #'convert-to-zeros bit-list)))) #'(lambda (data-there) (logior ior-pattern (logand and-pattern data-there)))))) (defconstant no-trans vinc::$$transport-type-no-transport) (defconstant trans vinc::$$transport-type-transport) (defconstant vis-evcp vinc::$$transport-type-visible-evcp) (defconstant write vinc::$$transport-type-write) (defconstant normal vinc::$$transporter-mode-normal) (defun load-boot-transporter-ram-data (data-list) (flet ((val (x) (if (eq x '*) '* (eval x)))) (dolist (data-element data-list) (let ((vma-boxed (val (first data-element))) (md-boxed (val (second data-element))) (datatype (val (third data-element))) (mstat (val (fourth data-element))) (mctl (val (fifth data-element))) (modifier (expand-data-modifier (nthcdr 5 data-element)))) (dotimes (vmab 2.) (when (lisp::or (eq '* vma-boxed) (= vma-boxed vmab)) (dotimes (mdb 2.) (when (lisp::or (eq '* md-boxed) (= mdb md-boxed)) (dotimes (dtp 64.) (when (lisp::or (eq '* datatype) (= dtp datatype)) (dotimes (type 4.) (when (lisp::or (eq '* mstat) (= type mstat)) (dotimes (mode 4.) (when (lisp::or (eq '* mctl) (= mctl mode)) (modify-boot-transporter-ram-data mode type dtp vmab mdb modifier))))))))))))))) ;;; Format of transporter ram data: ;;; (vma-boxed md-boxed datatype mstat mctl box-error trap-if-not-old trap-if-old trappable-pointer) (defparameter *transporter-ram-initial-data* '(;; Anything weird we trap on. (* * * * * 1 1 1 1) ;; Don't trap on unboxed-write if no gc-write-test, no trap on unboxed read if "no-transport" (0 0 * no-trans normal 0 0 0 0) ;; Don't trap on unboxed-write if no gc-write-test, trap on unboxed read if not "no-transport" (0 0 * vis-evcp normal 0 1 1 0) ;; NIL is not treated like a pointer in the transporter ram. (* 1 vinc:$$dtp-nil no-trans normal 1 1 1 1) (* 1 vinc:$$dtp-nil trans normal 0 0 0 0) (* 1 vinc:$$dtp-nil vis-evcp normal 1 0 0 1) (* 1 vinc:$$dtp-nil write normal 0 0 0 0) ;; FIXNUMS (* 1 vinc:$$dtp-fixnum no-trans normal 1 1 1 1) (* 1 vinc:$$dtp-fixnum trans normal 0 0 0 0) (* 1 vinc:$$dtp-fixnum vis-evcp normal 1 0 0 1) (* 1 vinc:$$dtp-fixnum write normal 0 0 0 0) ;; CHARACTERS same as fixnums (* 1 vinc:$$dtp-character no-trans normal 1 1 1 1) (* 1 vinc:$$dtp-character trans normal 0 0 0 0) (* 1 vinc:$$dtp-character vis-evcp normal 1 0 0 1) (* 1 vinc:$$dtp-character write normal 0 0 0 0) ;; ARRAY HEADER SINGLE not a pointer, but don't bash (* 1 vinc:$$dtp-array-header-single no-trans normal 1 1 1 1) (* 1 vinc:$$dtp-array-header-single trans normal 0 0 0 0) (* 1 vinc:$$dtp-array-header-single vis-evcp normal 1 0 0 1) (* 1 vinc:$$dtp-array-header-single write normal 1 1 1 1) ;; ARRAY (* 1 vinc:$$dtp-array no-trans normal 1 1 1 1) (* 1 vinc:$$dtp-array trans normal 0 0 1 1) (* 1 vinc:$$dtp-array vis-evcp normal 1 0 1 1) (* 1 vinc:$$dtp-array write normal 0 0 1 1) ;; CONS (* 1 vinc:$$dtp-cons no-trans normal 1 1 1 1) (* 1 vinc:$$dtp-cons trans normal 0 0 1 1) (* 1 vinc:$$dtp-cons vis-evcp normal 1 0 1 1) (* 1 vinc:$$dtp-cons write normal 0 0 1 1) ;; SYMBOL HEADER pointer, but don't bash (* 1 vinc:$$dtp-symbol-header no-trans normal 1 1 1 1) (* 1 vinc:$$dtp-symbol-header trans normal 0 0 1 1) (* 1 vinc:$$dtp-symbol-header vis-evcp normal 1 0 1 1) (* 1 vinc:$$dtp-symbol-header write normal 1 1 1 1) ;; SYMBOL (* 1 vinc:$$dtp-symbol no-trans normal 1 1 1 1) (* 1 vinc:$$dtp-symbol trans normal 0 0 1 1) (* 1 vinc:$$dtp-symbol vis-evcp normal 1 0 1 1) (* 1 vinc:$$dtp-symbol write normal 0 0 1 1) ;; UNBOUND (* 1 vinc:$$dtp-unbound no-trans normal 1 1 1 1) (* 1 vinc:$$dtp-unbound trans normal 0 1 1 1) (* 1 vinc:$$dtp-unbound vis-evcp normal 1 1 1 1) (* 1 vinc:$$dtp-unbound write normal 0 0 1 1) )) (defun load-transporter-ram-data () (load-boot-transporter-ram-data *transporter-ram-initial-data*)) ;;(defun load-boot-transporter-ram-data () ;; ;; All unused entries trap. ;; (dotimes (mode transporter-ram::*number-of-transporter-modes*) ;; (dotimes (type transporter-ram::*number-of-transport-types*) ;; (dotimes (md-byte transporter-ram::*number-of-transporter-md-byte-values*) ;; (let ((transporter-data 0.)) ;; (dotimes (vma-boxed 2.) ;; (dotimes (md-boxed 2.) ;; (setq transporter-data ;; (sim:k-dpb ;; (sim:k-ldb ;; (sim:k-dpb ;; hw::$$trappable-pointer sim::%%k-transporter-ram-trappable-pointer ;; (sim:k-dpb ;; hw::$$trap-if-oldspace sim::%%k-transporter-ram-trap-if-oldspace ;; (sim:k-dpb ;; hw::$$trap-if-not-oldspace sim::%%k-transporter-ram-trap-if-not-oldspace ;; (sim:k-dpb ;; hw::$$box-error sim::%%k-transporter-ram-box-error ;; 0)))) ;; (byte 4. 4.) ;; 0.) ;; (byte 4. (* 4. (+ (* vma-boxed 2) md-boxed))) ;; transporter-data)))) ;; (cold-data-write ;; (+ (cluster->address *initial-transporter-ram-data-physical-location*) ;; (sim:k-dpb ;; md-byte (byte (byte-size sim::%%k-transporter-md-byte) 0.) ;; (sim:k-dpb ;; type (byte (byte-size sim::%%k-memory-status-transport-ram-bits) ;; (byte-size sim::%%k-transporter-md-byte)) ;; (sim:k-dpb ;; mode (byte (byte-size sim::%%k-memory-control-transporter-mode) ;; (+ (byte-size sim::%%k-memory-status-transport-ram-bits) ;; (byte-size sim::%%k-transporter-md-byte))) ;; 0.)) ;; transporter-data))))) ;; ;; Normal mode, all unboxed never traps. ;; (let ((mode vinc::$$transport-mode-normal) ;; (vma-boxed $$unboxed) ;; (md-boxed $$unboxed)) ;; (dotimes (type *number-of-transport-types*) ;; (dotimes (md-byte *number-of-transporter-md-byte-values*) ;; (let* ((location ;; (+ (cluster->address *initial-transporter-ram-data-physical-location*) ;; (dpb-multiple-unboxed ;; md-byte (byte (byte-size %%k-transporter-md-byte) 0.) ;; type (byte (byte-size %%k-memory-status-transport-type) ;; (byte-size %%k-transporter-md-byte)) ;; mode (byte (byte-size %%k-memory-control-transporter-mode) ;; (+ (byte-size %%k-memory-status-transport-type) ;; (byte-size %%k-transporter-md-byte))) ;; 0.))) ;; (transporter-data (cold-data-write location))) ;; (setq transporter-data ;; (%dpb ;; (%ldb ;; (dpb-multiple-unboxed ;; $$non-trappable-pointer %%k-transporter-ram-trappable-pointer ;; $$dont-trap-if-oldspace %%k-transporter-ram-trap-if-oldspace ;; $$dont-trap-if-not-oldspace %%k-transporter-ram-trap-if-not-oldspace ;; $$no-box-error %%k-transporter-ram-box-error ;; 0.) ;; (byte 4. 4.) ;; 0.) ;; (byte 4. (* 4. (+ (* vma-boxed 2) md-boxed))) ;; transporter-data)) ;; (cold-data-write location transporter-data))))) ;; ;; Normal mode, type no-transport, never trans trap. ;; (let ((mode vinc::$$transport-mode-normal) ;; (type vinc::$$transport-type-no-transport)) ;; (dotimes (md-byte *number-of-transporter-md-byte-values*) ;; (let* ((location ;; (+ (cluster->address *initial-transporter-ram-data-physical-location*) ;; (dpb-multiple-unboxed ;; md-byte (byte (byte-size %%k-transporter-md-byte) 0.) ;; type (byte (byte-size %%k-memory-status-transport-type) ;; (byte-size %%k-transporter-md-byte)) ;; mode (byte (byte-size %%k-memory-control-transporter-mode) ;; (+ (byte-size %%k-memory-status-transport-type) ;; (byte-size %%k-transporter-md-byte))) ;; 0.))) ;; (transporter-data (cold-data-read location))) ;; (dotimes (vma-boxed 2.) ;; (dotimes (md-boxed 2.) ;; (setq transporter-data ;; (%dpb ;; (%ldb ;; (dpb-multiple-unboxed ;; $$dont-trap-if-oldspace %%k-transporter-ram-trap-if-oldspace ;; $$dont-trap-if-not-oldspace %%k-transporter-ram-trap-if-not-oldspace ;; $$no-box-error %%k-transporter-ram-box-error ;; (%ldb transporter-data (byte 4. (* 4. (+ (* vma-boxed 2) md-boxed))) 0.)) ;; (byte 4. 4.) ;; 0.) ;; (byte 4. (* 4. (+ (* vma-boxed 2) md-boxed))) ;; transporter-data)))) ;; (cold-data-write location transporter-data))))) ;(defun init-boot-vector-macro () ; (do ((tail (get-boot-vector-entries) (rest tail)) ; (count 0 (1+ count)) ; (code '() (cons `(SETQ ,(first (first tail)) (BOOT::READ-BOOT-VECTOR ,count)) code))) ; ((null tail) `(PROGN ,@(reverse code))))) ;(defun initialize-from-boot-vector () ; (eval (init-boot-vector-macro))) ;GAK! CHOKE! ARGH! (defparameter *quantum-devices* '(*null-paging-device*)) (defparameter *boot-quanta* (list ;; nil, t, and boot vector (list 0. '*null-paging-device* 1) ;; quantum map, region bits, and pcd (list 1. '*null-paging-device* 1) ;; code (list 2048. '*null-paging-device* 4.))) (defun build-cold-quantum-map () ;;; Don't know where the device vector will be yet. ; (do ((devices (reverse *quantum-devices*) (if devices (rest devices) nil)) ; (devnum 0 (1+ devnum))) ; ((or (null devices) (= devnum 16.)) ; (when devices ; (ferror nil "Too many quantum devices"))) ; (setf (aref *quantum-device-vector* devnum) ; (if devices ; (first devices) ; *null-paging-device* ; ))) ;; Zero all quanta. (dotimes (i vinc:*number-of-quanta*) (cold-data-write (+ i (cluster->address *quantum-map-physical-location*)) 0.)) ;; Write initial quanta. (dolist (q *boot-quanta*) (dotimes (number (third q)) (cold-data-write (+ (first q) (cluster->address *quantum-map-physical-location*) number) (dpb-multiple (zl::find-position-in-list (second q) *quantum-devices*) quantum-map::%%quantum-map-device (first q) quantum-map::%%quantum-map-region-origin quantum-map::$$quantum-mapped quantum-map::%%quantum-map-status 0.))))) ;;;;;;;;;;;;;;;;; ;;;; Region bits ;;;;;;;;;;;;;;;;; (defun get-boot-regions () (list ;; Resident symbols (list 0. ;quantum 0 1. ;one quantum long (region-bits:encode-region-bits region-bits:$$region-fixed region-bits:$$region-copy-space region-bits:$$region-space-structure region-bits:$$region-read-write region-bits:$$scavenge-enabled 0.)) ;swapin quantum 0 ;; Paging tables (list 1. ;quantum 1 1. ;one quantum long (region-bits:encode-region-bits region-bits:$$region-fixed region-bits:$$region-copy-space region-bits:$$region-space-unboxed region-bits:$$region-read-write region-bits:$$scavenge-disabled 0.)) ;swapin quantum 0 (list 2048. 4. (region-bits:encode-region-bits region-bits:$$region-fixed region-bits:$$region-copy-space region-bits:$$region-space-code region-bits:$$region-read-only region-bits:$$scavenge-enabled 16.)) )) (defun load-boot-region-bits () ;; Zero all the region bits. (let ((zapped (region-bits:encode-region-bits region-bits:$$region-fixed region-bits:$$region-copy-space region-bits:$$region-space-free region-bits:$$region-read-only region-bits:$$scavenge-disabled 0.))) (dotimes (i region-bits:*number-of-regions*) (cold-data-write (+ i (cluster->address *region-bits-physical-location*)) zapped )) (dolist (record (get-boot-regions)) (let ((quantum-start (first record)) (quantum-count (second record))) (do ((quantum quantum-start (1+ quantum)) (count quantum-count (1- count)) (region-bits (third record) (dpb region-bits:$$region-space-invalid region-bits::%%region-bits-space-type region-bits))) ((zerop count)) (cold-data-write (+ quantum (cluster->address *region-bits-physical-location*)) region-bits)))))) ;;;;;;;;;;;;;;;;; ;;;; Region data ;;;;;;;;;;;;;;;;; ;(defun create-region-data-for-cold-load () ; (let ((region-data (region-bits:make-region ; (ceiling (* region-bits:*number-of-regions* 4.) *qs-in-quantum*) ; (region-bits:parameters->region-bits ; region-bits:$$region-space-fixed ; region-bits:$$scavenge-disabled ; region-bits:$$region-read-write ; 15.) ;Swapin entire thing. ; 0.))) ;volatility 0. ; (setq region-data::*region-free-pointer* (quantum->address region-data)) ; (setq region-data::*region-allocation-status* (+ region-data::*region-free-pointer* ; region-bits:*number-of-regions*)) ; (setq region-data::*region-end* (+ region-data::*region-allocation-status* ; region-bits:*number-of-regions*)) ; (setq region-data::*region-gc-pointer* (+ region-data::*region-end* ; region-bits:*number-of-regions*)) ; ;; Bash data for initial regions. Do this right someday. ; (setf (region-data:region-free-pointer 0) (hw:dpb 1. vinc::%%quantum-number 0.)) ; (setf (region-data:region-allocation-status 0) 0) ; (setf (region-data:region-end 0) (hw:dpb 1. vinc::%%quantum-number 0.)) ; (setf (region-data:region-gc-pointer 0) (hw:dpb 1. vinc::%%quantum-number 0.)) ; (setf (region-data:region-free-pointer 1) (hw:dpb 2. vinc::%%quantum-number 0.)) ; (setf (region-data:region-allocation-status 1) 0) ; (setf (region-data:region-end 1) (hw:dpb 2. vinc::%%quantum-number 0.)) ; (setf (region-data:region-gc-pointer 1) (hw:dpb 2. vinc::%%quantum-number 0.)) ; ;; We ourselves is full. ; (setf (region-data:region-free-pointer region-data) ; (+ region-data::*region-gc-pointer* region-bits:*number-of-regions*)) ; (setf (region-data:region-allocation-status region-data) 0) ; (setf (region-data:region-end region-data) ; (+ region-data::*region-gc-pointer* region-bits:*number-of-regions*)) ; (setf (region-data:region-gc-pointer region-data) ; (+ region-data::*region-gc-pointer* region-bits:*number-of-regions*)) ; region-data ; )) ;(defun create-area-data-for-cold-load (region-data-region) ; (let* ((qs-needed (+ mem:*number-of-regions* ;Region list thread ; mem:*number-of-areas* ;Area region data ; mem:*number-of-areas* ;Area region bits ; mem:*number-of-areas* ;Area region size ; )) ; (quanta-needed (ceiling qs-needed *qs-in-quantum*)) ; (region-bits (region-bits:parameters->region-bits ; region-bits:$$region-space-fixed ; region-bits:$$scavenge-disabled ; region-bits:$$region-read-write ; (max 15. (1- (* quanta-needed *clusters-in-quantum*))))) ; (region (region-data:make-region quanta-needed region-bits 1))) ; (setq memlow:*region-list-thread* (region-data::region-free-pointer region)) ; (region-data::advance-free-pointer region mem:*number-of-regions*) ; (setq memlow:*area-region-data* (region-data::region-free-pointer region)) ; (region-data::advance-free-pointer region mem:*number-of-areas*) ; (setq memlow::*area-region-bits* (region-data::region-free-pointer region)) ; (region-data::advance-free-pointer region mem:*number-of-areas*) ; (setq memlow::*area-region-size* (region-data::region-free-pointer region)) ; (region-data::advance-free-pointer region mem:*number-of-areas*) ; (setf (region-data::region-gc-pointer region) (region-data::region-free-pointer region)) ; ;;; Zero out the area tables ; (dotimes (area mem:*number-of-areas*) ; (setf (area-data::area-region-data area) ; (hw:dpb area-data::$$area-free area-data::%%area-data-area-status 0.))) ; ;;; Setup RESIDENT SYMBOL AREA ; (setf (area-data::area-region-data 0.) ; (dpb-multiple-boxed ; area-data::$$area-fixed area-data::%%area-data-area-status ; 0. area-data::%%area-data-region-thread ; 0.)) ; (setf (area-data::region-list-thread 0.) ; (hw:dpb-boxed area-data::$$thread-ends area-data::%%region-list-thread-end-flag 0.)) ; (setf (area-data::area-region-size 0.) 0.) ; (setf (area-data::area-region-bits 0.) ; (dpb-multiple-boxed ; (region-bits::parameters->region-bits ; region-bits::$$region-space-fixed ; region-bits::$$scavenge-enabled ; region-bits::$$region-read-only ; 0.))) ; ;;; Setup PAGING TABLE AREA ; (setf (area-data::area-region-data 1.) ; (dpb-multiple-boxed ; area-data::$$area-fixed area-data::%%area-data-area-status ; 1. area-data::%%area-data-region-thread ; 0.)) ; (setf (area-data::region-list-thread 1.) ; (hw:dpb-boxed area-data::$$thread-ends area-data::%%region-list-thread-end-flag 1.)) ; (setf (area-data::area-region-size 1.) 0.) ; (setf (area-data::area-region-bits 1.) ; (dpb-multiple-boxed ; (region-bits::parameters->region-bits ; region-bits::$$region-space-fixed ; region-bits::$$scavenge-enabled ; region-bits::$$region-read-only ; 0.))) ; ;;; Setup MEMORY MANAGEMENT AREA ; (setf (area-data::area-region-data 2.) ; (dpb-multiple-boxed ; area-data::$$area-fixed area-data::%%area-data-area-status ; region-data-region area-data::%%area-data-region-thread ; 0.)) ; (setf (area-data::region-list-thread region-data-region) ; (hw:dpb-boxed area-data::$$thread-continues area-data::%%region-list-thread-end-flag region)) ; (setf (area-data::region-list-thread region) ; (hw:dpb-boxed area-data::$$thread-ends area-data::%%region-list-thread-end-flag region-data-region)) ; (setf (area-data::area-region-size 2.) 0.) ; (setf (area-data::area-region-bits 2.) region-bits))) (defun cold-load-data () (load-initial-map-data) (load-boot-gc-ram-data) (load-transporter-ram-data) (load-initial-physical-cluster-data) (build-cold-quantum-map) (load-boot-region-bits) ; ... ) ;(defun make-cold-load-but-dont-load-the-files (initial-function) ; (link-cold-loaded-functions) ; (cold-load-data) ; (cold-data-write (+ boot::**boot-vector-origin** boot::**initial-code-physical-location-bv-offset**) ; *cold-data-size*) ; (cold-data-write (+ boot::**boot-vector-origin** boot::**initial-code-size-in-clusters-bv-offset**) ; (1+ (ldb vinc::%%cluster-number (ash *cold-code-pointer* 2)))) ; (cold-data-write (+ boot::**boot-vector-origin** boot::**initial-code-entry-point-bv-offset**) ; (nc::ncompiled-function-starting-address (find-named-function initial-function))) ; (cold-data-write (+ boot::**boot-vector-origin** boot::*initial-gc-ram-data-physical-location*) ; *initial-gc-ram-data-physical-location*) ; (cold-data-write (+ boot::**boot-vector-origin** boot::*initial-transporter-ram-data-physical-location*) ; (cluster->address *initial-transporter-ram-data-physical-location*)) ; (user::dump-illop-codes)) (defun cold-write-boot-vector (offset data) (cold-data-write (+ boot::**boot-vector-origin** offset) data)) (defun make-cold-load (files initial-function) (cold-load-files files) (cold-load-data) (cold-write-boot-vector boot::**initial-code-physical-location-bv-offset** *cold-data-size*) (cold-write-boot-vector boot::**initial-code-size-in-clusters-bv-offset** (1+ (ldb vinc::%%cluster-number (ash *cold-code-pointer* 2)))) (cold-write-boot-vector boot::**initial-code-entry-point-bv-offset** (nc::ncompiled-function-starting-address (find-named-function initial-function))) (cold-write-boot-vector boot::*initial-gc-ram-data-physical-location* *initial-gc-ram-data-physical-location*) (cold-write-boot-vector boot::*initial-transporter-ram-data-physical-location* (cluster->address *initial-transporter-ram-data-physical-location*)) (cold-write-boot-vector boot::*cold-load-flag* 1) )