LMFL#!C(:HOST "SYS" :BACKUP-DATE 2760031830. :SYSTEM-TYPE :LOGICAL :VERSION 6. :TYPE "LISP" :NAME "NVRAM" :DIRECTORY ("REL3-SOURCE" "NVRAM") :SOURCE-PATTERN "( :DIRECTORY (\"REL3-SOURCE\") :NAME :WILD :TYPE :WILD :VERSION :NEWEST)" :VERSION-LIMIT 0. :CHARACTERS T :NOT-BACKED-UP T :CREATION-DATE 2758741292. :AUTHOR "REL3" :LENGTH-IN-BYTES 16290. :LENGTH-IN-BLOCKS 16. :BYTE-SIZE 8.)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 ;;; -*- Mode:Common-Lisp; Package:SI; Base:8 -*-;;;                           RESTRICTED RIGHTS LEGEND;;;Use, duplication, or disclosure by the Government is subject to;;;restrictions as set forth in subdivision (b)(3)(ii) of the Rights in;;;Technical Data and Computer Software clause at 52.227-7013.;;;                     TEXAS INSTRUMENTS INCORPORATED.;;;                              P.O. BOX 2909;;;                           AUSTIN, TEXAS 78769;;;                                 MS 2151;;; Copyright (C) 1985,1987 Texas Instruments Incorporated. All rights reserved.;;; This file contains functions to initialize and change NVRAM format and;;; parameter values.;;;    Setup-NVRAM must be run before crash record reporting;;; can begin, since it initializes the Crash Buffer data structure in NVRAM;;; (as well as other parameters used in STBM).;;;    Change-NVRAM can be used to modify existing STBM parameters in NVRAM.;;; Package dependencies: must be loaded into whatever package rest of NVRAM;;; system is in, but beyond that should work.  (All names defined outside;;; NVRAM system should carry explicit package prefix).;;; Edit History:;;; -------------;;; 3/85      rg   Original (as SETUP-NVRAM);;; 5/85      ab     Modified to use QDEV templates.;;; 9/85      ab     Renamed file NVRAM.;;;                  Modified both Setup-NVRAM and Change-NVRAM to understand;;;                logical unit numbers.  Added error checking.  Both now;;;                return strings describing current NVRAM parameters.  Improved;;;                documentation.;;;                  Change-NVRAM now only writes new values for supplied keyword;;;                parameters.;;;                  Removed Edit-NVRAM entirely. ;;;                  Use new field accessor macros where appropriate.;;;                  Prefixed all non-NVRAM names with explicit pkg.;;; 11/4/85   ab     NVRAM patch 2-7.  Changed default stream arg for NVRAM-Status;;;                to Standard-Output.;;; 11/86     kk   KK-1.  Changes to support NVRAM CRC field. Changed SETUP-NVRAM and;;;                  CHANGE-NVRAM to write CRC values.;;; 03-15-87  ab     Don't initialize "start-unallocated-area" or "number typed blocks".;;;                They are obsolete.;;; 03-29-87  ab     Added some typed-block support.  Change SETUP-NVRAM to make crash;;;                record buffer a typed block, and also to make a typed block for STBM.;;;                Also changed SETUP-NVRAM to initialize configuration checksum.;;;;;; Typed Block Support;;;(DEFUN initialize-typed-block-area ()  ;; Set all typed block area to #x+ABAB  (DO ((offset NVRAM-Start-Typed-Block-Area (+ offset 4)))      ((>= offset SIB-NVRAM-Length))    (write-nvram offset #x+AB))  ;; Make this area look like one big available typed block (up to Last-Typed-Block).  (write-nvram-16b (+ NVRAM-Start-Typed-Block-Area Typed-Block-ID-Offset)   Typed-Block-Available)  (write-nvram-16b (+ NVRAM-Start-Typed-Block-Area Typed-Block-Length-Offset)   (- NVRAM-Last-Typed-Block-Offset NVRAM-Start-Typed-Block-Area))  ;; Initialize Last Typed Block, which acts as an end marker.  ;; It has a special type (type "end") and 0-length data portion.  (write-nvram-16b (+ NVRAM-Last-Typed-Block-Offset Typed-Block-ID-Offset)   Typed-Block-End-Block)  (write-nvram-16b (+ NVRAM-Last-Typed-Block-Offset Typed-Block-Length-Offset)   (+ Typed-Block-Overhead-Length TB-End-Block-Length)))(DEFUN %initialize-typed-block (typed-block-code num-bytes start-offset)  (write-nvram-16b (+ start-offset Typed-Block-ID-Offset) typed-block-code)  (write-nvram-16b (+ start-offset Typed-Block-Length-Offset) (+ num-bytes Typed-Block-Overhead-Length))  (DO ((ct 0 (1+ ct))       (adr (+ start-offset Typed-Block-Overhead-Length)    (+ adr 4.)))      ((>= ct (TRUNCATE num-bytes 4.)));one NVRAM-byte per 4 Nubus-addressable bytes    (write-nvram adr 0)))(DEFUN %allocate-and-initialize-typed-block (typed-block-code data-length-in-bytes     block-to-carve-from     &optional (offset-into-block 0))  (LET ((new-block-total-bytes (+ data-length-in-bytes Typed-Block-Overhead-Length)) (old-type (read-nvram-16b (+ block-to-carve-from Typed-Block-ID-Offset)))(old-size (read-nvram-16b (+ block-to-carve-from Typed-Block-Length-Offset)))(new-block-addr (+ block-to-carve-from offset-into-block)))    (%initialize-typed-block typed-block-code data-length-in-bytes new-block-addr)    (COND ((= new-block-addr block-to-carve-from)   ;; Just move this block down & reduce its size to make room for new one.   (write-nvram-16b (+ block-to-carve-from new-block-total-bytes Typed-Block-ID-Offset)    old-type)   (write-nvram-16b (+ block-to-carve-from new-block-total-bytes Typed-Block-Length-Offset)    (- old-size new-block-total-bytes)))  (t   ;; Shorten old-block's length.   (write-nvram-16b (+ block-to-carve-from Typed-Block-Length-Offset)    offset-into-block)   ;; Make new available block after one to be inserted.   (write-nvram-16b (+ new-block-addr new-block-total-bytes Typed-Block-ID-Offset)    Typed-Block-Available)   (write-nvram-16b (+ new-block-addr new-block-total-bytes Typed-Block-Length-Offset)    (- old-size offset-into-block new-block-total-bytes))))    ))(DEFUN print-all-typed-blocks ()  (DO* ((adr NVRAM-Start-Typed-Block-Area     (+ adr block-length))(block-type (read-nvram-16b (+ adr Typed-Block-ID-Offset))    (read-nvram-16b (+ adr Typed-Block-ID-Offset)))(block-length (read-nvram-16b (+ adr Typed-Block-Length-Offset))      (read-nvram-16b (+ adr Typed-Block-Length-Offset)))res)       ((>= adr SIB-NVRAM-Length))    (FORMAT t "~%Block start: #x~4x    Block total length: #x~4x    Block type: #x~4x   ~a"    adr block-length block-type    (IF (SETQ res (DOLIST (type typed-block-type-codes)    (WHEN (= block-type (SYMBOL-VALUE type))      (RETURN type))))(FORMAT nil "(~a)" res)""))));;;;;; Internal functions;;;(Defun Nvram-Functioning-P (&Optional (Offset #o0))  "Simple check to see if we can read back a value written into NVRAM at OFFSET."  (Let ((Save1 (%Nubus-Read-8b-Careful Nvram-Slot (+ Nvram-Slot-Offset Offset)))(Save2 (%Nubus-Read-8b-Careful Nvram-Slot (+ Nvram-Slot-Offset Offset #o4))))    (When (Numberp Save1);if we could read anything successfully      (%Nubus-Write-8b Nvram-Slot (+ Nvram-Slot-Offset Offset) #o336)      (%Nubus-Write-8b Nvram-Slot (+ Nvram-Slot-Offset Offset #o4) #o67)      (Let ((Result     (If (And (Eql (%Nubus-Read-8b-Careful Nvram-Slot (+ Nvram-Slot-Offset Offset)) #o336) (Eql (%Nubus-Read-8b-Careful Nvram-Slot (+ Nvram-Slot-Offset Offset #o4)) #o67))       T       ())))(%Nubus-Write-8b Nvram-Slot (+ Nvram-Slot-Offset Offset) Save1)(%Nubus-Write-8b Nvram-Slot (+ Nvram-Slot-Offset Offset #o4) Save2)Result))))(Defun Initialize-Reserved-Areas ()  "Writes initial values out to all reserved locations recorded in NVRAM-Reserved list."  (Dolist (Res-List Nvram-Reserved Nil)    (Do ((Offset (First Res-List) (+ Offset #o4)) (Last (Second Res-List)) (Value (Third Res-List)))((= Offset Last))      (Write-Nvram Offset Value)))) (Defun Initialize-Crash-Rec-Pointers (Base Limit)  "Given BASE of crash record buffer area and LIMIT (both offsets from start of NVRAM)initialize the buffer area pointers."  (DECLARE (UNSPECIAL base))  (Let* ((Buffer-Size (- Limit Base)) (Number-Of-Records (Floor Buffer-Size Crash-Rec-Len)) (End-Of-Buff (+ Base (* Number-Of-Records Crash-Rec-Len))) (Last (- End-Of-Buff Crash-Rec-Len)))    (Cond      ((< Number-Of-Records #o1)       (Ferror "buffer too small -- not even room for one crash record"))      ((< Number-Of-Records #o4)       (Cerror :No-Action () () "Buffer is small -- only room for ~D crash records."       Number-Of-Records)))    (Write-Nvram-Field Nvram-Crash-Buff-Rec-Len Crash-Rec-Len)    (Write-Nvram-Field Nvram-Crash-Buff-Base Base)    (Write-Nvram-Field Nvram-Crash-Buff-Last Last)    (Write-Nvram-Field Nvram-Crash-Buff-Pointer Base)    (Write-Nvram-Field Nvram-Crash-Buff-Format-Rev Crash-Rec-Format-Version)    (Write-Nvram-Field Nvram-Crash-Buff-Format-Processor Crash-Rec-Format-Processor-Type)    ;; Return number of records    Number-Of-Records))(DEFUN initialize-first-crash-record ()  ;; For future expansion.  nil);;;;;; User-callable NVRAM functions.;;;;; NVRAM patch 2-7, -ab;; Change default stream arg to standard-output.(Defun Nvram-Status (&Optional (Stream *Standard-Output*))  "Writes the current status of NVRAM, including the default boot values, to STREAM."  (If (Not (Nvram-Functioning-P))    (Format Stream    "~%WARNING:  NVRAM does not appear to be functioning.  Have your SIB checked.")    (If (Not (Nvram-Initialized-P))      (Format Stream "~%NVRAM has not been initialized.  Use SI:Setup-NVRAM.")      (Progn(Format Stream"~%   Default Boot Unit is ~d. ~                            ~&   Default Boot Slot is ~d. ~                            ~&   Keyboard Unit is ~d. ~                            ~&   Keyboard Slot is ~d. ~                            ~&   Monitor Unit is ~d. ~                            ~&   Monitor Slot is ~d."(Get-Logical-Unit (Read-Nvram-Field Nvram-Boot-Unit))(Read-Nvram-Field Nvram-Boot-Slot) (Read-Nvram-Field Nvram-Keyboard-Unit)(Read-Nvram-Field Nvram-Keyboard-Slot) (Read-Nvram-Field Nvram-Monitor-Unit)(Read-Nvram-Field Nvram-Monitor-Slot)))))) (Defun Setup-Nvram (&Optional (Logical-Unit #o0))  "Initializes NVRAM in order to support system shutdown reportingand sets up the default disk unit from which the Lisp and microcode bands willbe loaded during a DEFAULT boot.  LOGICAL-UNIT is the logical disk unit number ofthe disk you wish to be the default load disk.  Since this function clears the current information stored in NVRAM, itshould only be run once after a system is installed, or after theSIB has been replaced or the NVRAM format used by the system has changed.To change the default load unit after NVRAM has been set up, use SI:Change-NVRAM.To examine the current values and state of NVRAM, use SI:NVRAM-Status."  (Check-Arg Logical-Unit     (And (Integerp Logical-Unit) (>= Logical-Unit #o0)(< Logical-Unit (Array-Dimension Disk-Type-Table #o0)))     "a valid disk logical unit number (an integer between 0 and 15.)")  (Let ((Ans T)(Slot (Ldb (Byte #o4 #o0) Nvram-Slot)))    (If (Not (Disk-Online Logical-Unit))      (Setq Ans    (Y-Or-N-P "~&Unit ~d is not currently online.  Use as default unit anyway?"      Logical-Unit)))    (If Ans      (If (Nvram-Functioning-P)(Progn  (Write-Nvram-Field Nvram-Monitor-Unit #o0)  (Write-Nvram-Field Nvram-Monitor-Slot Slot)  (Write-Nvram-Field Nvram-Keyboard-Unit #o0)  (Write-Nvram-Field Nvram-Keyboard-Slot Slot)  (Write-Nvram-Field Nvram-Boot-Unit (Convert-Logical-Unit-To-Physical Logical-Unit))  (Write-Nvram-Field Nvram-Boot-Slot (Ldb (Byte #o4 #o0) Nupi-Slot-Number))  (Write-Nvram-Field Nvram-Generation Nvram-Format-Generation-Number)  (Write-Nvram-Field Nvram-Revision Nvram-Format-Revision-Level);;;  (Write-Nvram-Field Nvram-Crc #o177777)               ;; old code KK-1  (Write-Nvram-Field Nvram-Crc (calc-nvram-crc))       ;; new code KK-1;;;  (Write-Nvram-Field Nvram-Config-Checksum #o177777)  (Write-Nvram-Field Nvram-Config-Checksum (calculate-config-checksum))  (Write-Nvram-Field Nvram-Shutdown-Valid-Character #o0)  (Write-Nvram-Field Nvram-Shutdown-Cause #o377)  (Write-Nvram-Field Nvram-Boot-Month #o0)  (Write-Nvram-Field Nvram-Boot-Day #o0)  (Write-Nvram-Field Nvram-Boot-Hour #o0)  (Write-Nvram-Field Nvram-Boot-Minute #o0)  (Write-Nvram-Field Nvram-Seconds-Since-Boot #o0)  (Write-Nvram-Field Nvram-Obsolete-1 #o10000);for downward-compatibility;;;  (Write-Nvram-Field Nvram-Start-Unallocated-Area #o10000);;;  (Write-Nvram-Field Nvram-Number-Typed-Blocks #o6)  (Initialize-Reserved-Areas)  ;; This must happen AFTER above are done.  (Initialize-Crash-Rec-Pointers si:NVRAM-Crash-Buffer-Start-Offset si:NVRAM-Crash-Buffer-Limit)  ;; Order cannot be changed for next three.  (initialize-typed-block-area)  (%allocate-and-initialize-typed-block    Typed-Block-Crash-Buffer TB-Crash-Buffer-Block-Length NVRAM-Start-Typed-Block-Area    (- NVRAM-Crash-Buffer-Start-Offset Typed-Block-Overhead-Length))  (%allocate-and-initialize-typed-block    Typed-Block-STBM TB-STBM-Block-Length NVRAM-Start-Typed-Block-Area)  (initialize-first-crash-record)  (Format () "~&NVRAM initialized successfully ~a" (Nvram-Status ())))"NVRAM initialization failed: unable to verify functioning of NVRAM.")))) (Defun Change-Nvram (&Key Load-Unit Load-Slot Monitor-Unit Monitor-Slot Keyboard-Unit Keyboard-Slot)  "Changes specific NVRAM parameters to support STBM acces to monitor,keyboard, and load source.   The most common use of this function is to change the disk unit used as the Lisp world load and microload source during a DEFAULT boot.Keywords are:   :LOAD-UNIT                    Logical disk unit for use in DEFAULT boot   :LOAD-SLOT     (normally 2).  Slot number of disk controller   :MONITOR-UNIT  (normally 0).  Monitor controller unit number   :MONITOR-SLOT  (normally 5).  Monitor controller slot number   :KEYBOARD-UNIT (normally 0).  Keyboard controller unit number   :KEYBOARD-SLOT (normally 5).  Keyboard controller slot number   Only supplied parameters are changed.  The funtion returns a string describing the current NVRAM parameter values (see also SI:NVRAM-Status)."  (When Load-Unit    (Check-Arg Load-Unit       (And (Integerp Load-Unit) (>= Load-Unit #o0)  (< Load-Unit (Array-Dimension Disk-Type-Table #o0)))       "a valid disk logical unit number (an integer between 0 and 15.)"))  (When Load-Slot    (Check-Arg Load-Slot (And (Integerp Load-Slot) (>= Load-Slot #o0)) "a positive integer"))  (When Monitor-Unit    (Check-Arg Monitor-Unit (And (Integerp Monitor-Unit) (>= Monitor-Unit #o0))       "a positive integer"))  (When Monitor-Slot    (Check-Arg Monitor-Slot (And (Integerp Monitor-Slot) (>= Monitor-Slot #o0))       "a positive integer"))  (When Keyboard-Unit    (Check-Arg Keyboard-Unit (And (Integerp Keyboard-Unit) (>= Keyboard-Unit #o0))       "a positive integer"))  (When Keyboard-Slot    (Check-Arg Keyboard-Slot (And (Integerp Keyboard-Slot) (>= Keyboard-Slot #o0))       "a positive integer"))  (Let ((Ans T))    (If (And Load-Unit (Not (Disk-Online Load-Unit)))      (Setq Ans    (Y-Or-N-P "~&Unit ~d is not currently online.  Use as default unit anyway? "      Load-Unit)))    (If Ans      (If (Nvram-Functioning-P)(Progn  (When Load-Unit    (Write-Nvram-Field Nvram-Boot-Unit (Convert-Logical-Unit-To-Physical Load-Unit)))  (When Load-Slot    (Write-Nvram-Field Nvram-Boot-Slot Load-Slot))  (When Monitor-Unit    (Write-Nvram-Field Nvram-Monitor-Unit Monitor-Unit))  (When Monitor-Slot    (Write-Nvram-Field Nvram-Monitor-Slot Monitor-Slot))  (When Keyboard-Unit    (Write-Nvram-Field Nvram-Keyboard-Unit Keyboard-Unit))  (When Keyboard-Slot    (Write-Nvram-Field Nvram-Keyboard-Slot Keyboard-Slot))  (If (Or Load-Unit Load-Slot Monitor-Unit Monitor-Slot Keyboard-Unit Keyboard-Slot)      (PROGN(Write-Nvram-Field Nvram-Crc (calc-nvram-crc))       ;; new code KK-1(Format () "~&NVRAM changes completed successfully. ~a"(Nvram-Status nil)))      (Format () "~&Current NVRAM parameters are: ~a"      (Nvram-Status nil))))"NVRAM changes failed: unable to verify functioning of NVRAM")      ;; User answered NO.  Tell him no changes made.      (Format nil "~&No changes made.  Current NVRAM parameters are: ~a" (Nvram-Status nil))))) (Defun NVRAM-DEFAULT-UNIT-AND-SLOT ()  "Returns the current default Unit and Slot specified by NVRAM."  (If (not (NVRAM-Functioning-P))      (ferror nil "~%WARNING:  NVRAM does not appear to be functioning.  Have your SIB checked.")      (If (not (NVRAM-initialized-p))  (Ferror nil "~%NVRAM has not been initialized.  Use SI:Setup-NVRAM.")  (values (Read-NVRAM-Field si:NVRAM-Boot-Unit) (Read-NVRAM-Field si:NVRAM-Boot-Slot))))) fix.    (If (= Load #o0)      "Name not recorded"      (Crec-Int-To-String Load #o4)))