;;; -*- 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 (c)(1)(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- 1989 Texas Instruments Incorporated. All rights reserved. ;;; ;;; This file contains functions that fill in parts of the crash record ;;; from Lisp. These functions are run on various init lists or are called ;;; from the Tm-Update process (also defined here). ;;; ;;; 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 sdk Original (part of CRASH-RECORD) ;;; 5/85 ab Put in SUPPORT-FUNCTIONS. Defined Tm-Update process to ;;; fill in time-since-boot from Lisp. ;;; 8/85 ab Added Record-Load-Unit function to fix up crash record ;;; fields after boot that the microcode doesn't always set up right. ;;; 9/85 ab Renamed file INITS. Put setup of NVRAM and Crash-Rec vars ;;; here also, as well as find-previous and find-next locators and ;;; 2 NVRAM access predicates which are used by the inits. ;;; Added generalized record-progress function. Put calls to ;;; it on system, cold and warm init lists to track boot progress better. ;;; General re-structuring of inits. ;;; Put tests in INIT functions to check if NVRAM accessible and ;;; initialized before reading/writing it. ;;; Use new field accessor macros. ;;; Prefixed all non-NVRAM names with explicit pkg. ;;; 11/4/85 RJF Fixed saving of year to be last two digits instead of always ;;; "19" (ie the first two digits) ;;; 11/86 kk KK-1. Changes to support NVRAM CRC field. Check this instead ;;; of NVRAM-Start-Unallocated-Area to see if NVRAM set up. ;;; Also, add initialization to make sure NVRAM CRC is set up, ;;; so people don't have to reinitialize NVRAM for Rel 3. ;;; Added new functions NEXT-NUBUS-CRC, which incrementally calculates ;;; a crc-byte, and CALC-NVRAM-CRC which returns the complete correct ;;; CRC for the current NVRAM contents. ;;; 3-15-87 ab Remove reference to NVRAM-Start-Unallocated-Area. It is obsolete field. ;;; 3-29-87 ab Added support for maintaing NVRAM chassis-configuration-checksum field. ;;; 07-13-87 ab NVRAM 2. Fix RECORD-LOAD-UNIT to coerce characters to integers before doing DPBs. ;;; 08-04-87 ab NVRAM 5. Implement TYPED-BLOCK accessors. [SPR 5119] ;;; 01.11.88 MBC Put NEXT-NUBUS-CRC back in --> needed for calculation cfg band's checksum. ;;; 01.12.88 MBC Conditionalize on resource-present-p and :NVRAM, :RTC, & :SOUND-CHIP. ;;; 01.13.88 MBC In add-initialization, conditionally call ASSURE-TYPED-BLOCK-AREA-SET-UP & ;;; SETUP-NVRAM-CRC based on (RESOURCE-PRESENT-P :NVRAM). ;;; ;;; NVRAM Access Predicates ;;; (Defun Nvram-Accessible-P () "Returns nil if we get an error trying to access NVRAM" (COND ((resource-present-p :NVRAM) (%Nubus-Read-8b-Careful Nvram-Slot Nvram-Slot-Offset)) (t t))) ;;AB 8/4/87. For now don't check format revision level. Part of work for [SPR 5119]. (Defun NVRAM-Initialized-p () "Simple test to see if NVRAM has been initialized with si:setup-nvram." (COND ((resource-present-p :NVRAM) (and (= (Read-NVRAM-Field si:NVRAM-CRC) (Calc-NVRAM-CRC)) ;kk-1 (= (Read-NVRAM-Field si:NVRAM-Generation) NVRAM-Format-Generation-Number))) (t (and (boundp 'addin:*crec-acb*) addin:*crec-acb*)))) ;;; ;;; Routines to initialze NVRAM and Crash-Record variables. ;;; ;; kk-1. ;; Temporary. Make sure CRC is set right, so people don't have to do SETUP-NVRAM again. ;; This function should only run once on any given system. ;;;(DEFUN setup-nvram-crc () ;;; (unused-function "setup-nvram-crc")) ;; KK-1. ;;;(DEFUN calc-nvram-crc (&rest ignore) ;;; (unused-function "calc-nvram-crc ")) (define-when :NVRAM (DEFUN setup-nvram-crc () (WHEN (AND (nvram-accessible-p) ;; This was old way of marking NVRAM as set up. ;;; (= (Read-NVRAM-Field si:NVRAM-Start-Unallocated-Area) #x+1000) (= (Read-NVRAM-Field si:NVRAM-CRC) #x+FFFF)) ; value put there by old code. (Write-NVRAM-Field si:NVRAM-CRC (Calc-NVRAM-CRC))) ) (DEFUN next-nubus-crc (old-crc data-byte) "Returns a CRC value calculated from and OLD-CRC value and a DATA-BYTE." (LOGXOR (DPB (LDB (BYTE 1. 7.) data-byte) ; data bit 7 (BYTE 1. 14.) (DPB (LDB (BYTE 1. 6.) data-byte) ; data bit 6 (BYTE 1. 12.) (DPB (LDB (BYTE 1. 5.) data-byte) ; data bit 5 (BYTE 1. 10.) (DPB (LDB (BYTE 2. 3.) data-byte) ; data bits 3,4 (BYTE 2. 7.) (DPB (LDB (BYTE 1. 2.) data-byte) ; data bit 2 (BYTE 1. 4.) (LOGAND #o0003 data-byte)))))) ; data bits 0,1 (DPB (LOGXOR old-crc (LDB (BYTE 1. 1.) old-crc) ; parity bit 00 (LDB (BYTE 1. 4.) old-crc) ; parity bit 01 (LDB (BYTE 1. 7.) old-crc) ; parity bit 04 (LDB (BYTE 1. 8.) old-crc) ; parity bit 07 (LDB (BYTE 1. 10.) old-crc) ; parity bit 10 (LDB (BYTE 1. 12.) old-crc) ; parity bit 12 (LDB (BYTE 1. 14.) old-crc)) ; parity bit 14 (BYTE 1. 15.) (LDB (BYTE 15. 1) old-crc)))) (DEFUN calc-nvram-crc (&aux crc) "Calculates and returns the NVRAM CRC value to be written to NVRAM, based on its current contents." (DECLARE (VALUES crc)) (SETQ crc 0) (DO ((offset 0 (+ offset 4.))) ((>= offset si:NVRAM-CRC) crc) (SETQ crc (next-nubus-crc crc (read-nvram offset))))) ;;; end of Define-When :NVRAM ) ;; KK-1. ;;; This is used by GENERATE-CRC-FOR-FIELD-IN-ARRAY in "IO; CFG-PRIMITIVES" to ;;; generate check sums for parts of the config band. Without this Explorer lashups correctly ;;; using config style booting cannot change their mcr/load band selections. 1.11.88 MBC ;;;(DEFUN next-nubus-crc (&rest ignore) ;;; (unused-function "next-nubus-crc ")) ;;; These vars must be set up before any NVRAM access can be done. ;;; Gets run during warm inits. (Defun Setup-NVRAM-Vars () "Set up addresses that we need to access NVRAM." (COND ((resource-present-p :NVRAM) (Setq Nvram-Slot Tv::Sib-Slot-Number Nvram-Slot-Offset Sib-Nvram-Offset)) (t (setf Current-Crash-Rec-Offset #x-100)))) (Defun (:cond (NOT (resource-present-p :NVRAM)) Crash-Rec-Find-Next) (Crash-Rec-Pointer) ;; Given a pointer to a crash record, return pointer to next crash record ;; in crash ring. ;; return 0 for mac (if (>= Crash-Rec-Pointer (- (* #x100 (Number-of-Crash-Records-In-Ring)) #x200)) (- (* #x100 (Number-of-Crash-Records-In-Ring)) #x200) (+ #x100 Crash-Rec-Pointer)) ) (Defun (:cond (resource-present-p :NVRAM) Crash-Rec-Find-Next) (Crash-Rec-Pointer) ;; Given a pointer to a crash record, return pointer to next crash record ;; in crash ring. (Let* ((Crec-Size (Read-Nvram-Field Nvram-Crash-Buff-Rec-Len)) (Crec-Buf-Last (Read-Nvram-Field Nvram-Crash-Buff-Last)) (Trial-Next (+ Crash-Rec-Pointer Crec-Size))) (If (<= Trial-Next Crec-Buf-Last) ;check for wrap around Trial-Next (Read-Nvram-Field Nvram-Crash-Buff-Base)) ;return ptr to first )) (Defun (:cond (NOT (resource-present-p :NVRAM)) Crash-Rec-Find-Previous) (Crash-Rec-Pointer) ;use later(Crash-Rec-Pointer) ;; Given a pointer to a crash record, return pointer to previous crash record ;; in crash ring. (if (> Crash-Rec-Pointer 0) (- Crash-Rec-Pointer #x100) (- (* #x100 (Number-of-Crash-Records-In-Ring)) #x200)) ) (Defun (:cond (resource-present-p :NVRAM) Crash-Rec-Find-Previous) (Crash-Rec-Pointer) ;; Given a pointer to a crash record, return pointer to previous crash record ;; in crash ring. (Let* ((Crec-Size (Read-Nvram-Field Nvram-Crash-Buff-Rec-Len)) (Crec-Buf-Base (Read-Nvram-Field Nvram-Crash-Buff-Base)) (Trial-Prev (- Crash-Rec-Pointer Crec-Size))) (If (>= Trial-Prev Crec-Buf-Base) ;check for wrap around Trial-Prev (Read-Nvram-Field Nvram-Crash-Buff-Last)) ;return ptr to last )) ;;; This must be initialized before current-crash-record access can be done. ;;; Gets run during warm inits. (Defun (:cond (NOT (resource-present-p :NVRAM)) Setup-Crash-Rec-Vars) () "Set up CURRENT-CRASH-RECORD-OFFSET with relative address of this boot's crash record." ;;;for single crash record saved on mac (Setq Current-Crash-Rec-Offset #x-100)) (Defun (:cond (resource-present-p :NVRAM) Setup-Crash-Rec-Vars) () "Set up CURRENT-CRASH-RECORD-OFFSET with relative address of this boot's crash record." (When (And (Nvram-Accessible-P) (Nvram-Initialized-P)) (Let ((Next-Crec (Read-Nvram-Field Nvram-Crash-Buff-Pointer))) (Setq Current-Crash-Rec-Offset (Crash-Rec-Find-Previous Next-Crec))))) ;;; ;;; Routines to fill in parts of the crash record from LISP. ;;; (Defun Record-Progress (Progress-Code) "Records progress into boot (represented by PROGRESS-CODE) in current crash record." (When (And (Nvram-Accessible-P) (Nvram-Initialized-P)) (Write-Current-Crash-Field Cro-Progress Progress-Code))) (Defun Record-Load-Unit () "Records name of Load band for this boot in NVRAM." (When (And (Nvram-Accessible-P) (Nvram-Initialized-P)) ;; If load partition name is 0, then was default boot and we need to fix. ;; Othewise, it was written correctly by Ucode crash record allocation routine. (When (= (Read-Current-Crash-Field Cro-Load-Part) #o0) ;; Need to fix unit number and name of current band. (Write-Current-Crash-Field Cro-Load-Unit Load-Unit) (Write-Current-Crash-Field Cro-Load-Part (Dpb (CHAR-INT (Aref *Loaded-Band* #o3)) (Byte #o10 #o30) (Dpb (CHAR-INT (Aref *Loaded-Band* #o2)) (Byte #o10 #o20) (Dpb (CHAR-INT (Aref *Loaded-Band* #o1)) (Byte #o10 #o10) (CHAR-INT (Aref *Loaded-Band* #o0))))))))) (Defun Record-System-Version () "Fills in system versionrevision fields in NVRAM after boot." (Multiple-Value-Bind (Version Revision) (Get-System-Version) (When (And (And Version Revision) (Nvram-Accessible-P) (Nvram-Initialized-P)) (Write-Current-Crash-Field Cro-Load-Version Version) (Write-Current-Crash-Field Cro-Load-Revision Revision)))) (Defun Record-Boot-Time () "Write boot time to NVRAM crash record. Called from warm init list. Must be called after initialize-timebase." (Multiple-Value-Bind (Ignore Mins Hrs Day Mon Yr) (Time:Get-Time) (When (And (And Mins Hrs Day Mon Yr) (Nvram-Accessible-P) (Nvram-Initialized-P)) ;; Write out boot time and initialize current time. (Write-Current-Crash-Field Cro-Boot-Month Mon) (Write-Current-Crash-Field Cro-Boot-Day Day) (Write-Current-Crash-Field Cro-Boot-Year (Rem Yr #o144)) (Write-Current-Crash-Field Cro-Boot-Hour Hrs) (Write-Current-Crash-Field Cro-Boot-Minute Mins) (Write-Current-Crash-Field Cro-Current-Month Mon) (Write-Current-Crash-Field Cro-Current-Day Day) (Write-Current-Crash-Field Cro-Current-Year (Rem Yr #o144)) (Write-Current-Crash-Field Cro-Current-Hour Hrs) (Write-Current-Crash-Field Cro-Current-Minute Mins)))) (DEFUN record-system-info-in-NVRAM () (Record-System-Version) (Record-Load-Unit) (Record-Boot-Time) (Record-Progress Crec-Progress-Time-Initialized) (WHEN (AND (resource-present-p :NVRAM) (nvram-accessible-p)) (WHEN (FBOUNDP 'calculate-config-checksum) (Write-Nvram-Field Nvram-Config-Checksum (calculate-config-checksum))))) ;;; ;;; Initialization-List Setup ;;; ;;; Do NOT change the order of these Add-Initialization's!! ;;; This goes on both System and Warm init lists. Goes on System so we can start recording ;;; progress then. Goes on warm so warm boots will be supported properly. ;;AB 8/12/87. Use :NORMAL keyword option so that inits are not run as encountered (because ;; some won't work until other files are loaded). ;;AB 7/30/87. Temp check for typed block area set up. Part of [SPR 5119] (Add-Initialization "Setup NVRAM Vars" '(Setup-NVRAM-Vars) '(:once)) (Add-Initialization "Initialize crash reporting parameters" '(PROGN (Setup-NVRAM-Vars) (WHEN (resource-present-p :NVRAM) ;1.13.88 MBC (assure-typed-block-area-set-up) (setup-nvram-crc)) (Setup-Crash-Rec-Vars) (Record-Progress si:CREC-Progress-System-Initializations)) ;; Put first on list. '(:head-of-list :system :normal)) (Add-Initialization "Record progress into boot" '(Record-Progress Crec-Progress-Cold-Initializations) '(:Head-Of-List :Cold :Normal)) (Add-Initialization "Initialize crash reporting parameters" '(Progn (Setup-Nvram-Vars) (Setup-Crash-Rec-Vars) (Record-Progress Crec-Progress-Warm-Initializations)) ;; Put first on list, because MUST go before error logging. '(:Head-Of-List :Warm :Normal)) (Add-Initialization "Record system information in NVRAM" '(Record-system-info-in-NVRAM) '(:Warm :Normal)) ;;; ;;; Here we define a background process that updates time field in current crash record every 5 ;;; minutes so we can know about how long the machine was up before it crashed. ;;; (Defun Update-Crec-Time () "Write current time to NVRAM crash record so that we can always know when we crashed. Called periodically from Tm-Update process." (Multiple-Value-Bind (Ignore Mins Hrs Day Mon Yr) (Time:Get-Time) (When (And (And Mins Hrs Day Mon Yr) (Nvram-Accessible-P) (Nvram-Initialized-P)) (Write-Current-Crash-Field Cro-Current-Month Mon) (Write-Current-Crash-Field Cro-Current-Day Day) (Write-Current-Crash-Field Cro-Current-Year (Rem Yr #o144)) (Write-Current-Crash-Field Cro-Current-Hour Hrs) (Write-Current-Crash-Field Cro-Current-Minute Mins)))) ;;; Define the Tm-Update process. Make sure it is re-started after resets and boots. Give it ;;; LOW priority. ;; NVRAM patch 2-2, -ab ;; Make initial function compiled instead of interpreted. (Process-Run-Function '(:Name "Tm-Update" :Restart-After-Reset T :Restart-After-Boot T :Priority #o-5) 'Tm-Update-Main-Loop) (DEFUN Tm-Update-Main-Loop () (LOOP (Update-Crec-Time) (WHEN (AND (FBOUNDP 'check-ecm-boards-for-errors) (NOT (mx-p))) (check-ecm-boards-for-errors)) ;defined in SYSLOG; ECM-BOARD-MONITORS (SLEEP 300.)))