; -*- Mode:Lisp; Package:LAMBDA; Base:8; readtable: ZL -*- ;DISK HANDLER FOR LAM FOR LAMBDA ; ** (c) Copyright 1980 - Massachusetts Institute of Technology ; ** (c) Copyright 1984,1985,1986 - Lisp Machine, Inc. ;****************************** ; STILL TO BE DONE ; FUNCTION TO VERIFY PAGE HASH TABLE, ALSO MAP? ;****************************** (DECLARE (SPECIAL LAM-DISK-ADDRESS LAM-DISK-RETRY-COUNT LAM-DISK-DA-DESC LAM-DISK-STATUS-DESC LAM-DISK-CMD-DESC LAM-DISK-READ-FCN LAM-DISK-WRITE-FCN LAM-DISK-TRACE-FLAG LAM-DISK-LAST-CMD LAM-DISK-LAST-CLP %SYS-COM-PAGE-TABLE-PNTR %SYS-COM-PAGE-TABLE-SIZE %%PHT1-VALID-BIT %%QF-PHT1-VIRTUAL-PAGE-NUMBER %%PHT2-PHYSICAL-PAGE-NUMBER %%PHT1-SWAP-STATUS-CODE %PHT-SWAP-STATUS-PDL-BUFFER %PHT-SWAP-STATUS-WIRED %PHT-SWAP-STATUS-FLUSHABLE %%PHT2-MAP-STATUS-CODE %%PHT2-ACCESS-STATUS-AND-META-BITS %PHT-MAP-STATUS-READ-WRITE %PHT-MAP-STATUS-PDL-BUFFER %PHT-DUMMY-VIRTUAL-ADDRESS MICRO-CODE-SYMBOL-AREA-START MICRO-CODE-SYMBOL-AREA-END PHT-ADDR INITIAL-LOD-NAME N-PARTITIONS N-HEADS N-CYLINDERS N-BLOCKS-PER-TRACK BLOCKS-PER-TRACK BLOCKS-PER-CYLINDER LAM-DISK-TYPE PARTITION-NAMES PARTITION-START PARTITION-SIZE CTALK-BARF-AT-WRITE-ERRORS)) (SETQ MICRO-CODE-SYMBOL-AREA-START 3 ;MAGIC MICRO-CODE-SYMBOL-AREA-END 7) ;MORE MAGIC (SETQ LAM-DISK-RETRY-COUNT 5) ;TIMES TO RETRY AT LAM-DISK-XFER IF GET ERROR ;(SETQ LAM-DISK-LAST-CMD 0 LAM-DISK-LAST-CLP 777) ;AVOID UNBOUND (SETQ LAM-DISK-TRACE-FLAG NIL) (DEFUN LAM-DISK-ANALYZE () (PRINT-IOPB) ) ;Look at the disk error log of the machine on the other end of the debug interface (DEFUN LAM-PRINT-DISK-ERROR-LOG () (DO I 600 (+ I 4) (= I 640) (LET ((CLP-CMD (PHYS-MEM-READ I)) (DA (PHYS-MEM-READ (1+ I))) (STS (PHYS-MEM-READ (+ I 2))) (MA (PHYS-MEM-READ (+ I 3)))) (COND ((NOT (ZEROP CLP-CMD)) (FORMAT T "~%Command ~O ~@[(~A) ~]" (LOGLDB 0020 CLP-CMD) (CDR (ASSQ (LOGLDB 0004 CLP-CMD) '((0 . "Read") (10 . "Read-Compare") (11 . "Write"))))) (FORMAT T "CCW-list pointer ~O (low 16 bits)~%" (LOGLDB 2020 CLP-CMD)) (FORMAT T "Disk address: unit ~O, cylinder ~O, head ~O, block ~O (~4:*~D ~D ~D ~D decimal)~%" (LOGLDB 3404 DA) (LOGLDB 2014 DA) (LOGLDB 1010 DA) (LOGLDB 0010 DA)) (FORMAT T "Memory address: ~O (type bits ~O)~%" (LOGLDB 0026 MA) (LOGLDB 2602 MA)) (FORMAT T "Status: ~O" STS) (DO ((PPSS 2701 (- PPSS 100)) (L '("Internal-parity" "Read-compare" "CCW-cycle" "NXM" "Mem-parity" "Header-Compare" "Header-ECC" "ELAM-Hard" "ECC-Soft" "Overrun" "Transfer-Aborted (or wr. ovr.)" "Start-Block-Error" "Timeout" "Seek-Error" "Off-Line" "Off-Cylinder" "Read-Only" "Fault" "No-Select" "Multiple-Select" "Interrupt" "Sel-Unit-Attention" "Any-Unit-Attention" "Idle") (CDR L))) ((MINUSP PPSS) (TERPRI)) (AND (LDB-TEST PPSS STS) (FORMAT T "~<~%~8X~:; ~A~>" (CAR L))))))))) ;Try harder routine. ;Get CYL, Head, Sector from disk, or from &OPTIONAL args. ;Try xfer again, with all flavors of offsets, and report. ;Then try recalibrate, all offsets again. (defun lam-try-harder (&OPTIONAL CYL head sector &aux (unit 0) disk-adr) disk-adr unit sector head cyl (BREAK "FOO") (COMMENT (cond ((null cyl) ;default from last xfer (setq disk-adr (phys-mem-read (+ lam-disk-address 2))) (setq cyl (ldb 2014 disk-adr) head (ldb 0808 disk-adr) sector (ldb 0008 disk-adr) unit (ldb 3403 disk-adr)))) (do recal 0 (1+ recal) (= recal 2) (do ((fcn-bits '(0 40 60 100 200 140 240 160 260) (cdr fcn-bits)) (fcn-name '("Normal" "Servo Reverse" "Servo Forward" "Strobe Early" "Strobe Late" "Servo Reverse -- Strobe Early" ;NO COMMAS INSIDE STRINGS "Servo Reverse -- Strobe Late" ; IN MACLISP "Servo Forward -- Strobe Early" "Servo Forward -- Strobe Late") (cdr fcn-name)) (lam-disk-retry-count 1)) ;for lam-disk-xfer-... ((null fcn-bits)) (format t "~%Trying with ~A ---" (car fcn-name)) ;; Read that block into core page 3 (phys-mem-write 1400 525252777) ;change data (SMD-SEEK 800.) ;random seek of cylinder (lam-disk-xfer-track-head-sector (car fcn-bits) cyl head sector 3 1) (lam-disk-op 6) ;Clear servo offset ; (compare) ) (cond ((= recal 0) (format t "~%[Recalibrating]") (lam-disk-op 1005) ;Recalibrate (lam-disk-wait-idle 4) ;wait Sel Unit Attention - recal done ))))) (defun lam-disk-recalibrate nil (BREAK "FOO") ) ;;; THESE ARE REALLY ONLY USED FOR READING THE LABEL ;;; DEFAULT TO eagle (formated at 512 bytes per sector) ; unfortunately sectors-per-track is defined in smd-disk.lisp - I hope it ; doesn't cause problems to use it here. (DEFCONST BLOCKS-PER-TRACK SECTORS-PER-TRACK) (DEFCONST BLOCKS-PER-CYLINDER (* SECTORS-PER-TRACK 20.)) ;(DEFCONST LAM-DISK-TYPE NIL) ;;; INITIALIZES DISK PARAMETERS (DEFUN LAM-DISK-INIT () ; (LET ((LAM-DISK-TYPE T))) (READ-LABEL) (cond ((or (zerop n-heads) (zerop n-blocks-per-track)) (ferror nil "n-heads=~s, n-blocks-per-track=~s, you will lose badly" n-heads n-blocks-per-track))) ; (SETQ BLOCKS-PER-CYLINDER (* N-HEADS N-BLOCKS-PER-TRACK)) ; (SETQ BLOCKS-PER-TRACK N-BLOCKS-PER-TRACK) ; (SETQ LAM-DISK-TYPE T) ) (defun lam-fake-disk-init-for-t302 () (setq n-heads 19.) (setq n-blocks-per-track 18.) ; (SETQ BLOCKS-PER-CYLINDER (* N-HEADS N-BLOCKS-PER-TRACK)) ; (SETQ BLOCKS-PER-TRACK N-BLOCKS-PER-TRACK) ; (SETQ LAM-DISK-TYPE T) ) ;SAME AS LAM-DISK-XFER, BUT TAKES ARGS IN TRACK, HEAD, SECTOR FORM. ; MAINLY GOOD FOR RETRYING TRANSFERS THAT LOSE, ETC. (DEFUN LAM-DISK-XFER-TRACK-HEAD-SECTOR (FCN TRACK HEAD SECTOR MB-ADR N-BLOCKS) fcn track head sector mb-adr n-blocks (ferror nil "can't work") (comment (LAM-DISK-XFER FCN (LIST TRACK HEAD SECTOR) MB-ADR N-BLOCKS) ) ) (DEFUN LAM-DISK-READ-VIA-MULTIBUS (DISK-BLOCK-NUM MB-ADR N-BLOCKS) ;(ferror nil "obsolete") (IF LAM-DISK-TRACE-FLAG (FORMAT T "~%LAM-DISK-READ-VIA-MULTIBUS block ~s mb-adr ~s nblocks ~s" DISK-BLOCK-NUM MB-ADR N-BLOCKS)) (LAM-DISK-XFER-VIA-MULTIBUS SMD-READ-COMMAND DISK-BLOCK-NUM MB-ADR N-BLOCKS)) (DEFUN LAM-DISK-READ-VIA-NUBUS (DISK-BLOCK-NUM CORE-PAGE-NUM N-BLOCKS) (IF LAM-DISK-TRACE-FLAG (FORMAT T "~%LAM-DISK-READ-VIA-NUBUS block ~s core-page-num ~s nblocks ~s" DISK-BLOCK-NUM CORE-PAGE-NUM N-BLOCKS)) (selectq current-processor-type (:lambda (LAM-DISK-XFER-VIA-NUBUS SMD-READ-COMMAND DISK-BLOCK-NUM CORE-PAGE-NUM N-BLOCKS)) (:explorer (cond ((= n-blocks 1) (nupi-read (send *proc* :page-band-unit) disk-block-num core-page-num n-blocks)) (t (ferror nil "foo")))))) (DEFUN LAM-DISK-WRITE-VIA-MULTIBUS (DISK-BLOCK-NUM MB-ADR N-BLOCKS) (ferror nil "obsolete") (IF LAM-DISK-TRACE-FLAG (FORMAT T "~%LAM-DISK-WRITE-VIA-MULTIBUS block ~s mb-adr ~s nblocks ~s" DISK-BLOCK-NUM MB-ADR N-BLOCKS)) (LAM-DISK-XFER-VIA-MULTIBUS SMD-WRITE-COMMAND DISK-BLOCK-NUM MB-ADR N-BLOCKS)) (DEFUN LAM-DISK-WRITE-VIA-NUBUS (DISK-BLOCK-NUM CORE-PAGE-NUM N-BLOCKS) (IF LAM-DISK-TRACE-FLAG (FORMAT T "~%LAM-DISK-WRITE-VIA-NUBUS block ~s core-page-num ~s nblocks ~s" DISK-BLOCK-NUM CORE-PAGE-NUM N-BLOCKS)) (selectq current-processor-type (:lambda (LAM-DISK-XFER-VIA-NUBUS SMD-WRITE-COMMAND DISK-BLOCK-NUM CORE-PAGE-NUM N-BLOCKS)) (:explorer (cond ((= n-blocks 1) (nupi-write (send *proc* :page-band-unit) disk-block-num core-page-num n-blocks)) (t (ferror nil "foo")))))) ;WRITE OUT ALL PAGES WHETHER OR NOT MODIFIED, SINCE WHEN THIS IS ;CALLED THEY OFTEN HAVEN'T GOTTEN TO DISK YET. ;(DEFUN LAM-DISK-WRITE-OUT-CORE (PARTITION-NAME) ; (ferror nil "can't work") ; (LET ((X (GET-PARTITION-START-AND-SIZE PARTITION-NAME))) ; (LET ((PARTITION-START (CAR X)) (PARTITION-SIZE (CDR X))) ; (DO ((PHT-LOC (QF-POINTER (PHYS-MEM-READ (+ 400 %SYS-COM-PAGE-TABLE-PNTR))) ; (+ 2 PHT-LOC)) ; (PHT-COUNT (// (QF-POINTER (PHYS-MEM-READ (+ 400 %SYS-COM-PAGE-TABLE-SIZE))) 2) ; (1- PHT-COUNT)) ; (PHT1) ; (PHT2)) ; ((= 0 PHT-COUNT)) ; (DECLARE (FIXNUM PHT-LOC PHT-COUNT PHT1 PHT2)) ; (AND (NOT (ZEROP (LOGLDB %%PHT1-VALID-BIT ; (SETQ PHT1 (PHYS-MEM-READ PHT-LOC))))) ;IF PAGE EXISTS ; (NOT (= (LOGLDB %%QF-PHT1-VIRTUAL-PAGE-NUMBER PHT1) ; %QF-PHT-DUMMY-VIRTUAL-ADDRESS)) ;AND ISN'T A DUMMY ; (PROGN ;THEN WRITE IT OUT ; (SETQ PHT2 (PHYS-MEM-READ (1+ PHT-LOC))) ; (OR (< (LOGLDB %%QF-PHT1-VIRTUAL-PAGE-NUMBER PHT1) PARTITION-SIZE) ; (ERROR '|Core doesn't fit in the partition; partition has been clobbered.| ; (LOGLDB %%QF-PHT1-VIRTUAL-PAGE-NUMBER PHT1) 'FAIL-ACT)) ; (LAM-DISK-WRITE-QUEUEING ; (+ PARTITION-START ; (LOGLDB %%QF-PHT1-VIRTUAL-PAGE-NUMBER PHT1)) ; (LOGLDB %%PHT2-PHYSICAL-PAGE-NUMBER PHT2) ; 1) ; (OR (= (LOGLDB %%PHT1-SWAP-STATUS-CODE PHT1) %PHT-SWAP-STATUS-WIRED) ; (PROGN ;IF NOT WIRED, REMOVE FROM CORE AND ; (PHYS-MEM-WRITE PHT-LOC ; (DPB %QF-PHT-DUMMY-VIRTUAL-ADDRESS ;STORE BACK DUMMY ENTRY ; %%QF-PHT1-VIRTUAL-PAGE-NUMBER ; (DPB %PHT-SWAP-STATUS-FLUSHABLE ; %%PHT1-SWAP-STATUS-CODE ; PHT1))) ; (PHYS-MEM-WRITE (1+ PHT-LOC) ; (LOGDPB 200 ;READ-ONLY ; %%PHT2-ACCESS-STATUS-AND-META-BITS PHT2))))))) ; ;NOW WRITE OUT THE PAGE HASH TABLE AGAIN SINCE IT'S BEEN MODIFIED ; ;1P AT A TIME SINCE MIGHT BE BIGGER THAN THE MAP OR SOMETHING ; ((LAMBDA (PHT-FIRST-PAGE PHT-N-PAGES) ; (DECLARE (FIXNUM PHT-FIRST-PAGE PHT-N-PAGES)) ; (DO ((DA (+ PARTITION-START PHT-FIRST-PAGE) (1+ DA)) ; (PG PHT-FIRST-PAGE (1+ PG)) ; (N PHT-N-PAGES (1- N))) ; ((= N 0)) ; (DECLARE (FIXNUM DA PG N)) ; (LAM-DISK-WRITE-QUEUEING DA PG 1))) ; (// (QF-POINTER (PHYS-MEM-READ (+ 400 %SYS-COM-PAGE-TABLE-PNTR))) 400) ; (// (QF-POINTER (PHYS-MEM-READ (+ 400 %SYS-COM-PAGE-TABLE-SIZE))) 400))) ; )) ;DONE, NO NEED TO FLUSH QUEUE SINCE NOT USING QUEUEING NOW ;(DEFUN LAM-DISK-READ-IN-CORE (PARTITION-NAME) ; (ferror nil "can't work") ; (LET ((X (GET-PARTITION-START-AND-SIZE PARTITION-NAME))) ; (LET ((PARTITION-START (CAR X))) ; (QF-CLEAR-CACHE T) ;INVALIDATING CONTENTS OF CORE ; (LAM-DISK-READ-QUEUEING (1+ (CAR X)) 1 1) ;GET SYSTEM-COMMUNICATION-AREA ; (DO ((PHT-LOC (QF-POINTER (PHYS-MEM-READ (+ 400 %SYS-COM-PAGE-TABLE-PNTR)))) ; (PHT-COUNT (// (+ 377 (QF-POINTER ; (PHYS-MEM-READ (+ 400 %SYS-COM-PAGE-TABLE-SIZE)))) ; 400)) ; ) ; NIL ; (DECLARE (FIXNUM PHT-LOC PHT-COUNT)) ; (DO J 0 (+ J 1) (NOT (< J PHT-COUNT)) ;GET PAGE-TABLE-AREA, 1P AT A TIME ; (LAM-DISK-READ-QUEUEING ; (+ PARTITION-START (// PHT-LOC 400) J) ; (+ (// PHT-LOC 400) J) ; 1))) ;NOW READ IN ALL THE PAGES ; (DO ((PHT-LOC (PHYS-MEM-READ (+ 400 %SYS-COM-PAGE-TABLE-PNTR)) (+ 2 PHT-LOC)) ; (PHT-COUNT (// (QF-POINTER (PHYS-MEM-READ (+ 400 %SYS-COM-PAGE-TABLE-SIZE))) 2) ; (1- PHT-COUNT)) ; (PHT1) ; (PG)) ; ((= 0 PHT-COUNT)) ; (DECLARE (FIXNUM PHT-LOC PHT-COUNT PHT1 PG)) ; (AND (NOT (ZEROP (LOGLDB %%PHT1-VALID-BIT (SETQ PHT1 (PHYS-MEM-READ PHT-LOC))))) ; (NOT (= (SETQ PG (LOGLDB %%QF-PHT1-VIRTUAL-PAGE-NUMBER PHT1)) ; %QF-PHT-DUMMY-VIRTUAL-ADDRESS)) ;NOT DUMMY ; ;; Don't read in the MICRO-CODE-SYMBOL-AREA, it's part of the ucode logically. ; (OR (< PG MICRO-CODE-SYMBOL-AREA-START) (NOT (< PG MICRO-CODE-SYMBOL-AREA-END))) ; (LAM-DISK-READ-QUEUEING ; (+ PARTITION-START PG) ; (LOGLDB %%PHT2-PHYSICAL-PAGE-NUMBER (PHYS-MEM-READ (1+ PHT-LOC))) ; 1))) ; ))) ;NO NEED TO EMPTY QUEUE SINCE NOT CURRENTLY USING QUEUEING (DEFCONST LAM-DISK-LOWCORE 10) (DEFCONST LAM-DISK-HIGHCORE 300) (DEFUN LAM-DISK-COPY-PARTITION (FROM-PARTITION TO-PARTITION) from-partition to-partition (ferror nil "can't work") (comment (LET ((FROM-DESC (GET-PARTITION-START-AND-SIZE FROM-PARTITION)) (TO-DESC (GET-PARTITION-START-AND-SIZE TO-PARTITION))) (LET ((FROM-START (CAR FROM-DESC)) (FROM-SIZE (CDR FROM-DESC)) (TO-START (CAR TO-DESC)) (TO-SIZE (CDR TO-DESC))) (COND ((< TO-SIZE FROM-SIZE) (OR (Y-OR-N-P "~A is smaller. Continue anyway? " TO-PARTITION) (FERROR NIL "~A is smaller than ~A." TO-PARTITION FROM-PARTITION)))) ;ALL NUMBERS WITHIN THIS DO ARE IN PAGES, NOT WORDS. (DO ((LOWCORE LAM-DISK-LOWCORE) ;DON'T SMASH BOTTOM 2K WITH SYSTEM-COMMUNICATION, ETC. (HIGHCORE LAM-DISK-HIGHCORE) ;ONLY RELY ON 48K BEING PRESENT (RELADR 0 (+ RELADR (- HIGHCORE LOWCORE)))) ;THIS IS RELATIVE LOC WITHIN PARTITION ((NOT (< RELADR (MIN FROM-SIZE TO-SIZE)))) (DECLARE (FIXNUM LOWCORE HIGHCORE MAP-SIZE RELADR COREADD TOGO)) (LAM-DISK-READ-QUEUEING (+ FROM-START RELADR) LOWCORE (MIN (- FROM-SIZE RELADR) (- HIGHCORE LOWCORE))) (LAM-DISK-WRITE-QUEUEING (+ TO-START RELADR) LOWCORE (MIN (- TO-SIZE RELADR) (- HIGHCORE LOWCORE))) ))) )) ;DONE, NO NEED TO EMPTY QUEUE IN THIS VERSION ;(DEFUN LAM-DISK-SAVE (PARTITION) ; (COND ((NUMBERP PARTITION) ; (SETQ PARTITION (INTERN (STRING-APPEND "LOD" (+ 60 PARTITION)))))) ; (GET-PARTITION-START-AND-SIZE PARTITION) ;CAUSE AN ERROR IF NOT A KNOWN PARTITION ; (LAM-DISK-WRITE-OUT-CORE 'PAGE) ; (LAM-DISK-COPY-PARTITION 'PAGE PARTITION) ; (LAM-DISK-READ-IN-CORE 'PAGE)) ;(DEFUN LAM-DISK-RESTORE NARGS ; (LET ((PARTITION (AND (= NARGS 1) (ARG 1)))) ; (COND ((NULL PARTITION) ; (AND (> NARGS 1) (ERROR '|TOO MANY ARGS - LAM-DISK-RESTORE| NARGS)) ; (LAM-DISK-INIT) ;Use pack editor to find out what is current default load ; (SETQ PARTITION INITIAL-LOD-NAME)) ; ((NUMBERP PARTITION) ; (SETQ PARTITION (INTERN (STRING-APPEND "LOD" (+ 60 PARTITION)))))) ; (GET-PARTITION-START-AND-SIZE PARTITION) ;CAUSE AN ERROR IF NOT A KNOWN PARTITION ; (LAM-DISK-COPY-PARTITION PARTITION 'PAGE) ; (LAM-DISK-READ-IN-CORE 'PAGE))) (DEFUN LAM-CHECK-PAGE-HASH-TABLE-ACCESSIBILITY () (qf-setup-pht-addr) (let ((table-number-entries (LSH (QF-POINTER (PHYS-MEM-READ (+ PAGE-SIZE %SYS-COM-PAGE-TABLE-SIZE))) -1))) (DO ((TABLE-ADR PHT-ADDR (+ TABLE-ADR 2)) (PHT1) (COUNT table-number-entries (1- COUNT)) (NUMBER-ERRORS 0) (virt-adr-mask (logand -400 %qf-pointer-mask)) (total-probes 0) (items-looked-up 0) (max-probes 0) (max-virt-adr nil) (dummies 0)) ((= COUNT 0) (format t "~%Max probes ~s (at ~s), avg probes ~s, items ~s, dummies ~s, table-size ~s" max-probes max-virt-adr (// (+ 0.0 total-probes) items-looked-up) items-looked-up dummies table-number-entries) NUMBER-ERRORS) (DECLARE (FIXNUM TABLE-ADR HASH-ADR COUNT)) (SETQ PHT1 (PHYS-MEM-READ TABLE-ADR)) (COND ((= 0 (LOGLDB %%PHT1-VALID-BIT PHT1))) ((= %QF-PHT-DUMMY-VIRTUAL-ADDRESS (LOGLDB %%QF-PHT1-VIRTUAL-PAGE-NUMBER PHT1)) ;DUMMY (setq dummies (1+ dummies))) (t (multiple-value-bind (hash-adr probes) (QF-PAGE-HASH-TABLE-LOOKUP-WITH-PROBES (LOGAND PHT1 VIRT-ADR-MASK)) (if (> probes max-probes) (setq max-probes probes max-virt-adr (LOGAND PHT1 VIRT-ADR-MASK))) (setq total-probes (+ total-probes probes) items-looked-up (1+ items-looked-up)) (cond ((NOT (= TABLE-ADR HASH-ADR)) (format t " HASH TABLE PAIR AT PHYS MEM ADR ~s NOT ACCESSIBLE. HASH LOOKUP RETURNS ~S. pht1: ~s pht2: ~s" TABLE-ADR HASH-ADR pht1 (phys-mem-read (1+ table-adr))) (SETQ NUMBER-ERRORS (1+ NUMBER-ERRORS)) )))))))) (DEFUN LAM-PRINT-PAGE-HASH-TABLE-WIRED-STATUS () (qf-setup-pht-addr) (DO ((TABLE-ADR PHT-ADDR (+ TABLE-ADR 2)) (PHT1) (COUNT (LSH (QF-POINTER (PHYS-MEM-READ (+ PAGE-SIZE %SYS-COM-PAGE-TABLE-SIZE))) -1) (1- COUNT))) ((= COUNT 0)) (DECLARE (FIXNUM TABLE-ADR HASH-ADR COUNT)) (SETQ PHT1 (PHYS-MEM-READ TABLE-ADR)) (COND ((= 0 (LOGLDB %%PHT1-VALID-BIT PHT1))) ((= %QF-PHT-DUMMY-VIRTUAL-ADDRESS (LOGLDB %%QF-PHT1-VIRTUAL-PAGE-NUMBER PHT1))) ;DUMMY ((= %PHT-SWAP-STATUS-WIRED (LOGLDB %%PHT1-SWAP-STATUS-CODE PHT1)) (FORMAT T "~%Table adr ~s: pht1 ~s, pht2 ~s" TABLE-ADR PHT1 (PHYS-MEM-READ (1+ TABLE-ADR))))))) (DEFUN LAM-CHECK-PAGE-HASH-TABLE (&optional physical-pages-of-memory &aux pp-seen-array) "check each entry of page hash table is within a valid region" (cond ((null physical-pages-of-memory) (setq physical-pages-of-memory 0) (dolist (m (send *proc* :memory-configuration-list)) (setq physical-pages-of-memory (+ physical-pages-of-memory (car m)))) (format t "~%Physical pages of memory = ~s" physical-pages-of-memory))) (setq pp-seen-array (make-array physical-pages-of-memory ':type art-1b)) (dotimes (c physical-pages-of-memory) (cond ((not (zerop (aref pp-seen-array c))) (ferror nil "pp-seen not initialized")))) (qf-setup-pht-addr) (DO ((TABLE-ADR PHT-ADDR (+ TABLE-ADR 2)) (PHT1) (COUNT (LSH (QF-POINTER (PHYS-MEM-READ (+ PAGE-SIZE %SYS-COM-PAGE-TABLE-SIZE))) -1) (1- COUNT)) (losers-no-region 0) (losers-bad-physical-page 0) (free-table-slots 0) (count-ok 0) (dummies-seen 0) (swap-status-normal 0) (swap-status-flushable 0) (swap-status-prepage 0) (swap-status-age-trap 0) (swap-status-wired 0) (rmb (QF-INITIAL-AREA-ORIGIN 'REGION-BITS))) ((= COUNT 0) (format t "~%~%OK ~S, losers-no-region ~s, losers-bad-physical-page ~s, free pht ~s" count-ok losers-no-region losers-bad-physical-page free-table-slots) (format t "~%dummies seen ~s swap status: normal ~s flushable ~s " dummies-seen swap-status-normal swap-status-flushable ) (format t "~% prepage ~s age-trap ~s wired ~s" swap-status-prepage swap-status-age-trap swap-status-wired) (format t "~%Physical pages not seen: ") (dotimes (c physical-pages-of-memory) (cond ((not (= 1 (aref pp-seen-array c))) (format t "~5S " c))))) (DECLARE (FIXNUM TABLE-ADR HASH-ADR COUNT)) (SETQ PHT1 (PHYS-MEM-READ TABLE-ADR)) (COND ((= 0 (LOGLDB %%PHT1-VALID-BIT PHT1)) (setq free-table-slots (1+ free-table-slots))) ((= %QF-PHT-DUMMY-VIRTUAL-ADDRESS (LOGLDB %%QF-PHT1-VIRTUAL-PAGE-NUMBER PHT1)) ;DUMMY (let ((pht2 (phys-mem-read (1+ table-adr)))) (aset 1 pp-seen-array (ldb %%pht2-physical-page-number pht2)) (incf dummies-seen))) (t (let* ((virt-adr (ash (ldb %%QF-pht1-virtual-page-number pht1) 8)) (region (qf-region-number-of-pointer virt-adr t)) (pht2 (phys-mem-read (1+ table-adr)))) (let ((code (ldb %%pht1-swap-status-code pht1))) (select code (%PHT-SWAP-STATUS-NORMAL (incf swap-status-normal)) (%PHT-SWAP-STATUS-FLUSHABLE (incf swap-status-flushable)) (%PHT-SWAP-STATUS-PREPAGE (incf swap-status-prepage)) (%PHT-SWAP-STATUS-AGE-TRAP (incf swap-status-age-trap)) (%PHT-SWAP-STATUS-WIRED (incf swap-status-wired)) (t (ferror nil "unknown swap status")))) (cond ((null region) (format t "~%Table adr ~s: pht1 ~s, pht2 ~s, no region" table-adr pht1 pht2) (setq losers-no-region (1+ losers-no-region))) ((not (< (ldb %%pht2-physical-page-number pht2) physical-pages-of-memory)) (format t "~%Table adr ~s: pht1 ~s, pht2 ~s, physical page too big" table-adr pht1 pht2) (setq losers-bad-physical-page (1+ losers-bad-physical-page))) ((not (= 0 (aref pp-seen-array (ldb %%pht2-physical-page-number pht2)))) (format t "~%Table adr ~s: pht1 ~s, pht2 ~s, pp seen twice" table-adr pht1 pht2)) (t (aset 1 pp-seen-array (ldb %%pht2-physical-page-number pht2)) (setq count-ok (1+ count-ok)) (let ((pht2-meta-bits (ldb %%pht2-meta-bits pht2)) (region-meta-bits (ldb %%region-meta-bits (phys-mem-read (+ region rmb))))) ;low two bits are volatility, which can differ. (cond ((not (= (dpb 0 (byte 2 0) ;%%pht2-volatility pht2-meta-bits) (dpb 0 (byte 2 0) region-meta-bits))) (format t "~%Table adr ~s, pht1 ~s, pht2 ~s, meta bits in region table differ from meta bits in PHT and map map ~s, pht2 ~s, region ~s" table-adr pht1 pht2 pht2-meta-bits region-meta-bits region) (format t "~% pht-meta-bits: ") (lam-print-meta-bits (ldb %%pht2-access-status-and-meta-bits pht2)) (format t "~% region-meta-bits: ") (lam-print-meta-bits (ldb %%region-map-bits (phys-mem-read (+ region rmb)))) )))))) )))) (DEFUN LAM-PRINT-PAGE-HASH-TABLE (&optional physical-pages-of-memory &aux pp-seen-array vp-seen-array) (cond ((null physical-pages-of-memory) (setq physical-pages-of-memory 0) (dolist (m (send *proc* :memory-configuration-list)) (setq physical-pages-of-memory (+ physical-pages-of-memory (car m)))) (format t "~%Physical pages of memory = ~s" physical-pages-of-memory))) (qf-setup-pht-addr) (setq pp-seen-array (make-array physical-pages-of-memory ':type art-1b)) (setq vp-seen-array (make-array 1_17. ':type art-1b)) (format t "~&Table-adr PHT1 PHT2") (DO ((TABLE-ADR PHT-ADDR (+ TABLE-ADR 2)) (PHT1) (PHT2) (COUNT (LSH (QF-POINTER (PHYS-MEM-READ (+ PAGE-SIZE %SYS-COM-PAGE-TABLE-SIZE))) -1) (1- COUNT)) (hole-size 0) (dummy-run-size 0) (count-ok 0) (dummy-count 0) (RMB (QF-INITIAL-AREA-ORIGIN 'REGION-BITS))) ((= COUNT 0) (cond ((not (zerop hole-size)) (format t "~%HOLES ~d" hole-size))) (cond ((not (zerop dummy-run-size)) (format t "~%DUMMIES ~d" dummy-run-size))) (format t "~%Count OK ~D, Total dummies ~D" count-ok dummy-count) ) (SETQ PHT1 (PHYS-MEM-READ TABLE-ADR)) (setq pht2 (phys-mem-read (1+ table-adr))) (COND ((= 0 (LOGLDB %%PHT1-VALID-BIT PHT1)) (setq hole-size (1+ hole-size)) (go nodummy)) ((= %QF-PHT-DUMMY-VIRTUAL-ADDRESS (LOGLDB %%QF-PHT1-VIRTUAL-PAGE-NUMBER PHT1)) ;DUMMY (setq dummy-count (1+ dummy-count)) (aset 1 pp-seen-array (ldb %%pht2-physical-page-number pht2)) (setq dummy-run-size (1+ dummy-run-size)) (go nohole)) (t (format t "~&~6o: ~6o ~6o" table-adr pht1 pht2) (let* ((virt-page (ldb %%QF-pht1-virtual-page-number pht1)) (virt-adr (ash virt-page 8)) (region (qf-region-number-of-pointer virt-adr t))) (cond ((not (zerop (aref vp-seen-array virt-page))) (format t "~&~6o: ~6o ~6o, virtual page seen twice" table-adr pht1 pht2))) (aset 1 vp-seen-array virt-page) (cond ((null region) (format t "~%Table adr ~s: pht1 ~s, pht2 ~s, no region" table-adr pht1 pht2)) ((not (< (ldb %%pht2-physical-page-number pht2) physical-pages-of-memory)) (format t "~%Table adr ~s: pht1 ~s, pht2 ~s, physical page too big" table-adr pht1 pht2)) ((not (= 0 (aref pp-seen-array (ldb %%pht2-physical-page-number pht2)))) (format t "~%Table adr ~s: pht1 ~s, pht2 ~s, pp seen twice" table-adr pht1 pht2)) (t (aset 1 pp-seen-array (ldb %%pht2-physical-page-number pht2)) (setq count-ok (1+ count-ok)) (let ((pht2-meta-bits (ldb %%pht2-meta-bits pht2)) (region-meta-bits (ldb %%region-meta-bits (phys-mem-read (+ region rmb))))) (cond ((not (= pht2-meta-bits region-meta-bits)) (format t "~%Table adr ~s, pht1 ~s, pht2 ~s, meta bits in region table differ from meta bits in PHT and map map ~s, pht2 ~s, region ~s" table-adr pht1 pht2 pht2-meta-bits region-meta-bits region) (format t "~% pht-meta-bits: ") (lam-print-meta-bits (ldb %%pht2-access-status-and-meta-bits pht2)) (format t "~% region-meta-bits: ") (lam-print-meta-bits (ldb %%region-map-bits (phys-mem-read (+ region rmb)))) )))))))) (cond ((not (zerop hole-size)) (format t "~%HOLES ~d" hole-size) (setq hole-size 0))) nodummy (cond ((not (zerop dummy-run-size)) (format t "~%DUMMIES ~d" dummy-run-size) (setq dummy-run-size 0))) (go x) nohole (cond ((not (zerop hole-size)) (format t "~%HOLES ~d" hole-size) (setq hole-size 0))) X)) (defun lam-check-address-space-map () (LET ((RO (QF-INITIAL-AREA-ORIGIN 'REGION-ORIGIN)) (RL (QF-INITIAL-AREA-ORIGIN 'REGION-LENGTH)) (BYTES-PER-WORD (TRUNCATE 32. lam-%ADDRESS-SPACE-MAP-BYTE-SIZE)) (ENTRY-MASK (1- (LSH 1 lam-%ADDRESS-SPACE-MAP-BYTE-SIZE))) (ASM-AREA-NUMBER (FIND-POSITION-IN-LIST 'ADDRESS-SPACE-MAP (QF-INITIAL-AREA-LIST))) (number-regions (QF-POINTER (PHYS-MEM-READ (+ 400 %SYS-COM-NUMBER-REGIONS))))) (LET ((ASM-ORIGIN (QF-POINTER (PHYS-MEM-READ (+ RO ASM-AREA-NUMBER)))) (ASM-LENGTH (QF-POINTER (PHYS-MEM-READ (+ RL ASM-AREA-NUMBER)))) (SHIFT-PER-ENTRY (MINUS (TRUNCATE 32. BYTES-PER-WORD))) (VIRT-ADR 0)) (DOTIMES (REL-ADR ASM-LENGTH) (LET ((WD (PHYS-MEM-READ (+ REL-ADR ASM-ORIGIN)))) (DOTIMES (B BYTES-PER-WORD) (LET* ((R (LOGAND ENTRY-MASK WD)) (THAT-RO (QF-POINTER (PHYS-MEM-READ (+ RO R)))) (THAT-RL (QF-POINTER (PHYS-MEM-READ (+ RL R))))) (COND ((ZEROP R)) ((NOT (AND (>= VIRT-ADR THAT-RO) (< VIRT-ADR (+ THAT-RO THAT-RL)))) (FORMAT T "~%ADR MAP ENTRY VIRTUAL ADDRESS ~S SAYS REGION ~S, BUT THAT REGION STARTS AT ~S AND IS ~S LONG" VIRT-ADR R THAT-RO THAT-RL)))) (SETQ WD (ASH WD SHIFT-PER-ENTRY) VIRT-ADR (+ VIRT-ADR %ADDRESS-SPACE-QUANTUM-SIZE))))) (format t "~%Checking of a.s.m. entries completed, now checking regions vs a.s.m.") (let ((first-interesting-region (FIND-POSITION-IN-LIST 'init-list-area (QF-INITIAL-AREA-LIST))) (free-area-bitmap (lam-make-free-area-bitmap))) (dotimes (r number-regions) ;%sys-com-number-regions (cond ((lam-region-active-p r free-area-bitmap) (let* ((r-ro (qf-pointer (phys-mem-read (+ ro r)))) (r-rl (qf-pointer (phys-mem-read (+ rl r)))) (r-ro-in-pages (// r-ro si:page-size))) (if (>= r first-interesting-region) ;avoid random printouts for low (small) areas. (do ((relp 0 (1+ relp))) ((>= (* relp si:page-size) r-rl)) (let ((asm-e (lam-ref-address-space-map (+ r-ro-in-pages relp)))) (cond ((not (= r asm-e)) (format t "~%Page ~s of region ~s has incorrect A.S.M entry ~s" relp r asm-e))))))))))) ))) (defun lam-region-active-p (r &optional free-area-bitmap) (LET (;(A-N (QF-INITIAL-AREA-ORIGIN 'AREA-NAME)) (A-RL (QF-INITIAL-AREA-ORIGIN 'AREA-REGION-LIST)) ;(A-RS (QF-INITIAL-AREA-ORIGIN 'AREA-REGION-SIZE)) ;(A-MS (QF-INITIAL-AREA-ORIGIN 'AREA-MAXIMUM-SIZE)) (R-LT (QF-INITIAL-AREA-ORIGIN 'REGION-LIST-THREAD))) (if (null free-area-bitmap) (setq free-area-bitmap (lam-make-free-area-bitmap))) (DO-NAMED TOP ((AREA 0 (1+ AREA))) ((= AREA (1- number-of-areas)) nil) (if (zerop (aref free-area-bitmap area)) (DO ((RN (LOGLDB %%QF-POINTER (QF-MEM-READ (+ A-RL AREA))) (LOGLDB %%QF-POINTER (QF-MEM-READ (+ R-LT RN))))) ((LDB-TEST %%QF-BOXED-SIGN-BIT RN) (COND ((NOT (= AREA (LOGAND RN 777777))) (format t "Region thread not linked back to AREA for area ~s!!" area)))) (if (= r rn) (return-from top area))))))) (defun lam-make-free-area-bitmap () (let ((array (make-array number-of-areas :type :art-1b)) (A-RL (QF-INITIAL-AREA-ORIGIN 'AREA-REGION-LIST)) (f-an (QF-POINTER (PHYS-MEM-READ (+ 400 %SYS-COM-FREE-AREA#-LIST))))) (do ((free-area f-an (logldb %%qf-pointer (qf-mem-read (+ a-rl free-area))))) ((zerop free-area) (return array)) (aset 1 array free-area)))) (defun lam-print-free-area-list () (LET (;(A-N (QF-INITIAL-AREA-ORIGIN 'AREA-NAME)) (A-RL (QF-INITIAL-AREA-ORIGIN 'AREA-REGION-LIST)) ;(A-RS (QF-INITIAL-AREA-ORIGIN 'AREA-REGION-SIZE)) ;(A-MS (QF-INITIAL-AREA-ORIGIN 'AREA-MAXIMUM-SIZE)) (F-AN (QF-POINTER (PHYS-MEM-READ (+ 400 %SYS-COM-FREE-AREA#-LIST))))) (do ((free-area f-an (logldb %%qf-pointer (qf-mem-read (+ a-rl free-area))))) ((zerop free-area)) (format t "~%Area ~D. free" free-area)))) ;address space map has one entry per quantum (64. now) pages. ; note: these values can be pretty random for pages below INIT-LIST-AREA (defun lam-ref-address-space-map (p) (let* ((asm-divisor (// %address-space-quantum-size si:page-size)) (quantum (// p asm-divisor)) (BYTES-PER-WORD (TRUNCATE 32. lam-%ADDRESS-SPACE-MAP-BYTE-SIZE)) (WORD (PHYS-MEM-READ (+ (QF-INITIAL-AREA-ORIGIN 'ADDRESS-SPACE-MAP) (TRUNCATE QUANTUM BYTES-PER-WORD))))) (LOGAND (1- (LSH 1 lam-%ADDRESS-SPACE-MAP-BYTE-SIZE)) (ASH WORD (- (* (\ QUANTUM BYTES-PER-WORD) lam-%ADDRESS-SPACE-MAP-BYTE-SIZE)))))) (defun lam-check-physical-page-data () (let ((RO (QF-INITIAL-AREA-ORIGIN 'REGION-ORIGIN)) (RL (QF-INITIAL-AREA-ORIGIN 'REGION-LENGTH)) (ppd-AREA-NUMBER (FIND-POSITION-IN-LIST 'PHYSICAL-PAGE-DATA (QF-INITIAL-AREA-LIST))) (pht-area-number (find-position-in-list 'page-table-area (qf-initial-area-list)))) (let* ((ppd-origin (QF-POINTER (PHYS-MEM-READ (+ RO ppd-AREA-NUMBER)))) (ppd-LENGTH (QF-POINTER (PHYS-MEM-READ (+ RL ppd-AREA-NUMBER)))) (ppd-valid-length (qf-pointer (lam-symbolic-examine-register 'a-v-physical-page-data-valid-length))) ;; (ppd-active-end (qf-pointer (lam-symbolic-examine-register ;; 'a-v-physical-page-data-end))) (ppd-active-length ppd-valid-length) (pht-origin (qf-pointer (phys-mem-read (+ ro pht-area-number)))) (pht-length (qf-pointer (phys-mem-read (+ rl pht-area-number)))) (pht-index-limit (lam-symbolic-examine-register 'a-pht-index-limit)) ) (format t "~&pht-index-limit = ~s" pht-index-limit) (if (> pht-index-limit pht-length) (format t "~&pht-index-limit (~s) is bigger than pht-length (~s)" pht-index-limit pht-length)) (if (> ppd-valid-length ppd-length) (format t "~&ppd-valid-length (~s) is bigger than ppd-length (~s)" ppd-valid-length ppd-length)) (dotimes (rel-adr ppd-active-length) (let* ((wd (phys-mem-read (+ rel-adr ppd-origin))) (pht-index (ldb 0020 wd))) (cond ((not (= 177777 pht-index)) (cond ((not (< pht-index pht-index-limit)) (format t "~%PHYSICAL-PAGE-DATA ent ~s has out of range" rel-adr)) ((not (zerop (logand 1 pht-index))) (format t "~%PHYSICAL-PAGE-DATA ent ~s has odd pht-index ~s" rel-adr pht-index)) (t (let ((pht1 (phys-mem-read (+ pht-index pht-origin))) (pht2 (phys-mem-read (1+ (+ pht-index pht-origin))))) (cond ((not (= (ldb %%pht2-physical-page-number pht2) rel-adr)) (format t "~%PHYSICAL-PAGE-DATA ent ~s points to PHT ent ~s, the physical-page of which does not match. pht1= ~s, pht2= ~s" rel-adr pht-index pht1 pht2))))))))))))) (DEFUN GET-PARTITION-START-AND-SIZE (PARTITION-NAME) (LAM-DISK-INIT) (DO ((I 0 (1+ I))) ((NOT (< I N-PARTITIONS)) (ERROR '|No such partition| PARTITION-NAME)) (COND ((inhibit-style-warnings (SAMEPNAMEP (ARRAYCALL T PARTITION-NAMES I) PARTITION-NAME)) (RETURN (CONS (ARRAYCALL FIXNUM PARTITION-START I) (ARRAYCALL FIXNUM PARTITION-SIZE I))))))) ;Called on startup (analogous to the PDUMP function on the 10) (DEFUN LAM-INITIALIZE-ON-STARTUP () (SETQ LAM-FULL-SAVE-VALID NIL) (SETQ LAM-PASSIVE-SAVE-VALID NIL) ;(SETQ LAM-DISK-TYPE NIL) ) (ADD-INITIALIZATION "LAMBDA" '(LAM-INITIALIZE-ON-STARTUP) '(BEFORE-COLD)) (defun lam-load-new-microcode (partition) "after you reassemble the microcode, just run this function to get ready to use it." (initialize-disk-control) (print-disk-label "lam") (format t "Putting new microcode on partition ~A. " partition) (cond ((y-or-n-p "Ok? ") (format t "~%Copying micro code to eagle.") (si:load-lmc-file "lambda-ucode;ulambda.lmc" partition) (format t "~%Setting current micro load.") (lam-set-current-microload partition) (format t "~%Loading symbols.") (lam-load-ucode-symbols "lambda-ucode;ulambda.lmc-sym") (print-disk-label "lam") t) (t ())))