;;; -*- Mode:LISP; Package:LAMBDA; Base:8; Readtable:ZL -*-

(DefConst NVRAM-SLOT-OFFSET #xFA0000)

(DEFCONST NVRAM-quad-SLOT #xf5)

(Defsubst Exp-read-nVRAM (offset)
  "Read byte of NVRAM at address OFFSET from start of NVRAM."
  ;(%NuBus-Read-8 NVRAM-SLOT (+ NVRAM-SLOT-OFFSET offset))
  (send *proc* :bus-quad-slot-read-byte nvram-quad-slot (+ nvram-slot-offset offset))
  )

(Defsubst Exp-write-nVRAM (offset value)
  "Write least significant byte of VALUE into NVRAM at address OFFSET from start of NVRAM."
  ;(%NuBus-Write-8 NVRAM-SLOT (+ NVRAM-SLOT-OFFSET offset) value)
  (send *proc* :bus-quad-slot-write-byte nvram-quad-slot (+ nvram-slot-offset offset)
	value)
  )

(Defsetf Exp-read-nVRAM Exp-write-nVRAM)

(Defun Exp-read-nVRAM-16B (offset)
  "Read half-word of NVRAM (LSB first) at address OFFSET from start of NVRAM." 
  (Let ((lo-8 (Exp-read-nVRAM offset))
	(hi-8 (Exp-read-nVRAM (+ offset 4))))
    (Dpb hi-8 1010 lo-8)))

(Defun Exp-write-nVRAM-16B (offset value)
  "Write least significant 16 bits of VALUE into NVRAM.  LSB is written first."
  (Let ((lo-8 (Ldb 0010 value))
	(hi-8 (Ldb 1010 value)))
    (Exp-write-nVRAM offset lo-8)
    (Exp-write-nVRAM (+ offset 4) hi-8)))

(DefSetf Exp-read-nVRAM-16B Exp-write-nVRAM-16B)

(Defun Exp-write-nVRAM-24B (offset value)
  "Write least significant 24 bits of VALUE into NVRAM, LSB first."
  (Let ((lo-8 (Ldb 0010 value))
	(mid-8 (Ldb 1010 value))
	(hi-8 (Ldb 2010 value)))
    (Exp-write-nVRAM offset lo-8)
    (Exp-write-nVRAM (+ offset 4) mid-8)
    (Exp-write-nVRAM (+ offset 8.) hi-8)))

(Defun Exp-read-nVRAM-24B (offset)
  "Read 3 bytes of NVRAM starting at OFFSET, LSB first."
  (Let ((lo-8 (Exp-read-nVRAM offset))
	(mid-8 (Exp-read-nVRAM (+ offset 4)))
	(hi-8 (Exp-read-nVRAM (+ offset 8.))))
    (Dpb hi-8 2010 (Dpb mid-8 1010 lo-8))))

(DefSetf Exp-read-nVRAM-24B Exp-write-nVRAM-24B)

(Defun Exp-write-nVRAM-32B (offset value)
  "Write least significant 32 bits of VALUE into NVRAM, LSB first."
  (Let ((lo-16 (Ldb 0020 value))
	(hi-16 (Ldb 2020 value)))
    (Exp-write-nVRAM-16B offset lo-16)
    (Exp-write-nVRAM-16B (+ offset 8.) hi-16)))

(Defun Exp-read-nVRAM-32B (offset)
  "Read 4 bytes of NVRAM starting at OFFSET, LSB first."
  (Let ((lo-16 (Exp-read-nVRAM-16B offset))
	(hi-16 (Exp-read-nVRAM-16B (+ offset 8.))))
    (Dpb hi-16 2020 lo-16))) 

(DefSetf Exp-read-nVRAM-32B Exp-write-nVRAM-32B)

(Defun Dump-NVRAM ()
  "Dump all NVRAM locations.  For debugging."
  (Do ((offset 0 (+ offset 32.)))
      ((= offset #x2000) nil)
    (Format t "~&~16r -- ~16r  ~16r  ~16r  ~16r  ~16r  ~16r  ~16r  ~16r"
	    offset
	    (Exp-read-nVRAM offset)
	    (Exp-read-nVRAM (+ offset 4))
	    (Exp-read-nVRAM (+ offset 8.))
	    (Exp-read-nVRAM (+ offset 12.))
	    (Exp-read-nVRAM (+ offset 16.))
	    (Exp-read-nVRAM (+ offset 20.))
	    (Exp-read-nVRAM (+ offset 24.))
	    (Exp-read-nVRAM (+ offset 28.)))))

;;; Current crash record.  8-bit forms
(Defun Read-Current-Crash-Record (offset)
  "Read byte at location OFFSET in current crash record."
  (Exp-read-nVRAM (+ offset CURRENT-CRASH-RECORD-OFFSET)))

;;; Current crash record. 16-bit forms
(Defun Read-Current-Crash-Record-16B (offset)
  "Read half-word at OFFSET in current crash record, LSB first."
  (Exp-read-nVRAM-16B (+ offset CURRENT-CRASH-RECORD-OFFSET)))

;;; Any crash record. 8-bit forms
(Defun Read-Crash-Record (crash-record-pointer offset)
  "Read byte at location OFFSET in crash record."
  (Exp-read-nVRAM (+ offset crash-record-pointer)))

;;; Any crash record. 16-bit forms
(Defun Read-Crash-Record-16B (crash-record-pointer offset)
 "Read half-word at OFFSET in crash record, LSB first."
 (Exp-read-nVRAM-16B (+ offset crash-record-pointer)))

;;; Any crash record. 32-bit forms
(Defun Read-Crash-Record-32B (crash-record-pointer offset)
  "Read 32 bit word stored at OFFSET into crash record, from LSB to MSB."
  (Dpb (Exp-read-nVRAM-16B (+ offset crash-record-pointer 8.))
       2020
       (Exp-read-nVRAM-16B (+ offset crash-record-pointer))))


(DEFCONST CRASH-RECORD-FORMAT-PROCESSOR-TYPE 0)
(DEFCONST CRASH-RECORD-FORMAT-VERSION 1)
(DEFCONST CRASH-RECORD-LENGTH 224.)
(DEFCONST NVRAM-CRASH-BUFFER-FORMAT-PROCESSOR 128.)
(DEFCONST NVRAM-CRASH-BUFFER-FORMAT-REV 136.)
(DEFCONST NVRAM-CRASH-BUFFER-POINTER 144.)	; points to free crash record
(DEFCONST NVRAM-CRASH-BUFFER-RECORD-LENGTH 152.)
(DEFCONST NVRAM-CRASH-BUFFER-LAST 160.)
(DEFCONST NVRAM-CRASH-BUFFER-BASE 168.)

(DefConst NVRAM-MONITOR-UNIT 0)
(DefConst NVRAM-MONITOR-SLOT 12.)
(DefConst NVRAM-KEYBOARD-UNIT 16.)
(DefConst NVRAM-KEYBOARD-SLOT 28.)
(DefConst NVRAM-BOOT-UNIT 32.)
(DefConst NVRAM-BOOT-SLOT 44.)

(DefConst NVRAM-Reserved '((72. 80. 0.) (88. 96. 0.) (140. 144. 0.) (176. 240. 0.) (256. 8192. 255.)))

(DefConst NVRAM-FORMAT-GENERATION-NUMBER 1)
(DefConst NVRAM-FORMAT-REVISION-LEVEL 1)
(DefConst NVRAM-GENERATION 48.)
(DefConst NVRAM-REVISION 52.)
(DefConst NVRAM-CRC 56.)
(DefConst NVRAM-CONFIG-CHECKSUM 64.)
(DefConst NVRAM-SHUTDOWN-VALID-CHARACTER 80.)
(DefConst NVRAM-SHUTDOWN-CAUSE 84.)
(DefConst NVRAM-BOOT-MONTH 96.)
(DefConst NVRAM-BOOT-DAY 100.)
(DefConst NVRAM-BOOT-HOUR 104.)
(DefConst NVRAM-BOOT-MINUTE 108.)
(DefConst NVRAM-SECONDS-SINCE-BOOT 112.)
(DefConst NVRAM-START-UNALLOCATED-AREA 240.)
(DefConst NVRAM-NUMBER-TYPED-BLOCKS 248.)

;;; CRO - Crash Record Offset

(DefConst CRO-Progress 0)
(DefConst CRO-CONTROLLER 4)
(DefConst CRO-Ucode-Unit 8.)
(DefConst CRO-Load-Unit 12.)
(DefConst CRO-Ucode-Part 16.)
(DefConst CRO-Load-Part 32.)
(DefConst CRO-Ucode-Version 48.)
(DefConst CRO-Load-Version 56.)
(DefConst CRO-Load-Revision 64.)
(DefConst CRO-BOOT-MONTH 72.)
(DefConst CRO-BOOT-DAY 76.)
(DefConst CRO-BOOT-YEAR 80.)
(DefConst CRO-BOOT-HOUR 84.)
(DefConst CRO-BOOT-MINUTE 88.)
(DefConst CRO-CURRENT-MONTH 92.)
(DefConst CRO-CURRENT-DAY 96.)
(DefConst CRO-CURRENT-YEAR 100.)
(DefConst CRO-CURRENT-HOUR 104.)
(DefConst CRO-CURRENT-MINUTE 108.)
(DefConst CRO-Report-Flags 112.)
(DefConst CRO-Halt-Addr 116.)
(DefConst CRO-HALT-KIND 124.)
(DefConst CRO-M-1 128.)
(DefConst CRO-M-2 144.)
(DefConst CRO-MD 160.)
(DefConst CRO-VMA 176.)
(DefConst CRO-UPCSTK-0 192.)
(DefConst CRO-UPCSTK-1 200.)
(DefConst CRO-UPCSTK-2 208.)
(DefConst CRO-UPCSTK-3 216.)


(DefConst CREC-Progress-Decode
	  '(0 INITIAL-VALUE
	    5. ALLOCATED-CRASH-RECORD
	    20. STARTING-LISP
	    30. LISP-REINITIALIZE
	    40. CRASH-LIST-STARTED
	    50. DONE-WITH-CRASH-LIST
	    60. SYSTEM-INITIALIZATIONS
	    70. COLD-INITIALIZATIONS
	    80. WARM-INITIALIZATIONS
	    90. TIME-INITIALIZED
	    100. LISP-ENVIRONMENT))

(DefConst CREC-SYSTEM-BOOT 0)
(DefConst CREC-UCODE-HALT 1)
(DefConst CREC-HARDWARE-HALT 2)
(DefConst CREC-LISP-HALT 3)

(DefConst CREC-Progress-Initial-Value 0)
(DefConst CREC-Progress-Warm-Initializations 80.)
(DefConst CREC-PROGRESS-TIME-INITIALIZED 90.)
(DefConst CREC-PROGRESS-MAX 100.)

(DefConst %%CREC-Recorded-in-Log 0101)

;;;
;;; Crash Record locating routines.
;;;

(Defun Find-Previous-Crash-Record (crash-record-pointer)
  "Given a pointer to a crash record, return pointer to previous crash record
in crash ring."
  (Let* ((crec-size (Exp-read-nVRAM-16B NVRAM-CRASH-BUFFER-RECORD-LENGTH))
	 (crec-buffer-base (Exp-read-nVRAM-16B NVRAM-CRASH-BUFFER-BASE))
	 (trial-prev (- crash-record-pointer crec-size)))
    (If (>= trial-prev crec-buffer-base)
	trial-prev
      (Exp-read-nVRAM-16B NVRAM-CRASH-BUFFER-LAST))
    ))
						
(Defun Find-Next-Crash-Record (crash-record-pointer)
  "Given a pointer to a crash record, return pointer to next crash record
in crash ring."
  (Let* ((crec-size (Exp-read-nVRAM-16B NVRAM-CRASH-BUFFER-RECORD-LENGTH))
	 (crec-buffer-last (Exp-read-nVRAM-16B NVRAM-CRASH-BUFFER-LAST))
	 (trial-next (+ crash-record-pointer crec-size)))
    (If (<= trial-next crec-buffer-last)
	trial-next
      (Exp-read-nVRAM-16B NVRAM-CRASH-BUFFER-BASE))
    ))

(Defun Number-of-Crash-Records-in-Ring ()
  "Returns total number of crash records in crash ring."
  (Let ((crec-size (Exp-read-nVRAM-16B NVRAM-CRASH-BUFFER-RECORD-LENGTH))
	(crec-buffer-last (Exp-read-nVRAM-16B NVRAM-CRASH-BUFFER-LAST))
	(crec-buffer-first (Exp-read-nVRAM-16B NVRAM-CRASH-BUFFER-BASE)))
    ;; last points before last record so add one
    (1+ (truncate (- crec-buffer-last crec-buffer-first)
		  crec-size))))

(Defun All-Crash-Records
       (&optional (current-crec (exp-read-nvram-16b nvram-crash-buffer-pointer)))
  "Returns list of all crash record offsets, current record first."
  (Do* ((n (1- (Number-of-Crash-Records-in-Ring)) (1- n))
	;; since getting all can go forward to get them in reverse
	;;  order making it easier to cons them into a list.
        (crec (Find-Next-Crash-Record current-crec)
	     (Find-Next-Crash-Record crec))
	(l (Ncons crec) (Cons crec l))
	)
       ((Zerop n) l)))

(defun print-all-crash-records ()
  (dolist (c (all-crash-records))
    (dump-crec c)))

(Defun Dump-Crec (crec &optional (stream terminal-io))
  "Dumps out crec in semi-human-readable form.  For debugging.  If
STREAM is a string, it is interpreted as a filename, and output goes there."
  (With-Open-Stream (S (If (Stringp stream)
			     (Open (Fs:Parse-Pathname stream)
				   :direction :output)
			     stream)) 
      (Format S "~%CRASH RECORD #x~16r"        crec)
      (Format s "~%Progress = ~d."            (Read-Crash-Record     crec CRO-PROGRESS))
      (Format s "~%Controller = ~d."          (Read-Crash-Record     crec CRO-CONTROLLER))
      (Format s "~%Ucode unit = #x~16r"       (Read-Crash-Record     crec CRO-UCODE-UNIT))
      (Format s "~%Load unit = #x~16r"        (Read-Crash-Record     crec CRO-LOAD-UNIT))
      (Format s "~%Ucode partition = #x~16r"  (Read-Crash-Record-32b crec CRO-UCODE-PART))
      (Format s "~%Load partition = #x~16r"   (Read-Crash-Record-32b crec CRO-LOAD-PART))
      (Format s "~%Ucode version = ~d."       (Read-Crash-Record-16b crec CRO-UCODE-VERSION))
      (Format s "~%Load version = ~d."        (Read-Crash-Record-16b crec CRO-LOAD-VERSION))
      (Format s "~%Load revision = ~d."       (Read-Crash-Record-16b crec CRO-LOAD-REVISION))
      (Format s "~%Boot month = ~d."          (Read-Crash-Record     crec CRO-BOOT-MONTH))
      (Format s "~%Boot day = ~d."            (Read-Crash-Record     crec CRO-BOOT-DAY))
      (Format s "~%Boot year = ~d."           (Read-Crash-Record     crec CRO-BOOT-YEAR))
      (Format s "~%Boot hour = ~d."           (Read-Crash-Record     crec CRO-BOOT-HOUR))
      (Format s "~%Boot minute = ~d."         (Read-Crash-Record     crec CRO-BOOT-MINUTE))
      (Format s "~%Current month = ~d."       (Read-Crash-Record     crec CRO-CURRENT-MONTH))
      (Format s "~%Current day = ~d."         (Read-Crash-Record     crec CRO-CURRENT-DAY))
      (Format s "~%Current year = ~d."        (Read-Crash-Record     crec CRO-CURRENT-YEAR))
      (Format s "~%Current hour = ~d."        (Read-Crash-Record     crec CRO-CURRENT-HOUR))
      (Format s "~%Current minute = ~d."      (Read-Crash-Record     crec CRO-CURRENT-MINUTE))
      (Format s "~%Report-flags = #x~16r"     (Read-Crash-Record     crec CRO-REPORT-FLAGS))
      (Format s "~%Halt address = #x~16r"     (Read-Crash-Record-16b crec CRO-HALT-ADDR))
      (Format s "~%Halt kind = ~d."           (Read-Crash-Record     crec CRO-HALT-KIND))
      (Format s "~%CRO-M-1 = #x~16r"          (Read-Crash-Record-32b crec CRO-M-1))
      (Format s "~%CRO-M-2 = #x~16r"          (Read-Crash-Record-32b crec CRO-M-2))
      (Format s "~%CRO-MD = #x~16r"           (Read-Crash-Record-32b crec CRO-MD))
      (Format s "~%CRO-VMA = #x~16r"          (Read-Crash-Record-32b crec CRO-VMA))
      (Format s "~%CRO-UPCSTK-0 = #x~16r"     (Read-Crash-Record-16b crec CRO-UPCSTK-0))
      (Format s "~%CRO-UPCSTK-1 = #x~16r"     (Read-Crash-Record-16b crec CRO-UPCSTK-1))
      (Format s "~%CRO-UPCSTK-2 = #x~16r"     (Read-Crash-Record-16b crec CRO-UPCSTK-2))
      (Format s "~%CRO-UPCSTK-3 = #x~16r"     (Read-Crash-Record-16b crec CRO-UPCSTK-3))
      (Format s "~%---------------------------------------")))

