;+
; Project     :	SOHO - CDS
;
; Name        :	BOOTINFO
;
; Purpose     :	Extracts the boot info from the primary memory dump and displays results.
;
; Explanation : Either receives primary memory dump as an argument or reads the memory dump file.
;               Extracts info. from the bootstrap workspace area.
;               Displays some information on the code modules.
;               Calculates checksums for the code modules from memory dump and compares with bootstrap
;               records.
;
; Use         : <bootinfo, mem, GROUP=group>
;
; Inputs      : None.
;
; Opt. Outputs:	mem : primary memory dump array, if not present reads from memory dump file.
;
; Keywords    : GROUP : The ID of the parent widget.
;
; Calls       :	cp_dps_strarr, get_utc.
;                
; Common      :	None.
;
; Restrictions:	None.
;
; Side effects:	None.
;
; Category    :	Operations..
;
; Prev. Hist. :	None.
;
; Written     :	Version 0.0, Martin Carter, RAL, 9/1/96
;
; Modified    : Version 0.1, MKC, 11/1/96
;                            Added call to cp_dsp_strarr.
;               Version 0.2, MKC, 15/01/96
;                            Added current time to printout.
;                            Corrected status messages.
;
; Version     :	Version 0.2, 15/1/96
;-
;**********************************************************

PRO bootinfo, mem, GROUP=group

  ; test whether to retrieve memory dump from file

  IF N_ELEMENTS(mem) EQ 0 THEN BEGIN

    ; set up mem for restore

    mem = 0

    ; read in memory dump array

    RESTORE, GETENV ( 'CDS_MEM_DUMP' ) + '/primary.dump'

  ENDIF

  ; set up string array for bootstrp status

  statuses = [ 'Coldstart', $
               'SCIF init fail', $
               'Memory edit absolute request', $
               'Memory edit active request',   $
               'Memory edit extended request', $
               'Upload parameters request',    $
               'Upload code request', $
               'Activate request', $
               'Delete extended process request', $
               'Delete extended all request', $
               'Execute request', $
               'Clear EPROM reload request', $
               'Unknown bootstrap request', $
               'Block wait timeout', $
               'Block too small', $
               'Block bad data size', $
               'Bad upload pid', $
               'Bad activate request', $
               'PCV failed', $
               'Corrupt p check', $
               'Corrupt c check', $
               'Corrupt patch', $
               'Process reload', $
               'Bad full reload', $
               'Full reload', $
               'Interrupted MLB', $
               'Bad MLA header', $
               'SCIF read timeout', $
               'SCIF write timeout', $
               'ML checksum error', $
               'Bad block length', $
               'MLB timeout' ]

  ; set up string array for processes

  modules  = [ 'Harness2', 'CDHS kernel hi', 'CDHS kernel lo', 'Watchdog', $
               'Events',  'ML parser', 'CDHS eng', 'Primary router', $
               'Eng. acq.', 'Telemetry', 'SPC', 'CDS HK', $
               'Clock', 'Macro7', 'Exposure controller', 'IEF controller', $
               'MCU decode', 'MCU heater backup', 'Mechanism', 'SFT process', $
               'IMIF', 'Special module', 'Deferred module', 'Health monitor', $
               'Memory dump', 'Packetization', 'Two Transputer', 'IIF detect', $  
               'Science', 'Compression', 'Secondary', 'Macro support']

  ; set up string array for sources

  sources = [ 'UNKNOWN', 'EPROM', 'NEW', 'OLD', 'TEST', 'EMPTY', 'COMPRESS' ]

  ; set up results structures

  active = { code_start:LONARR(32), code_size:LONARR(32), ws_req:LONARR(32), $
             vs_req:LONARR(32), eof_point:LONARR(32), p_check:LONARR(32), $
             c_check:LONARR(32), patched:LONARR(32) }

  extended = active

  ; get bootstrap report status

  bsr = mem(125)

  ; get active arrays

  temp = LONG(mem(416:671),0,32,8)

  active.patched    = temp(*,0)
  active.c_check    = temp(*,1)
  active.p_check    = temp(*,2)
  active.eof_point  = temp(*,3)
  active.vs_req     = temp(*,4)
  active.ws_req     = temp(*,5)
  active.code_size  = temp(*,6)
  active.code_start = temp(*,7) 

  ; get extended arrays

  temp = LONG(mem(160:415),0,32,8)

  extended.patched    = temp(*,0)
  extended.c_check    = temp(*,1)
  extended.p_check    = temp(*,2)
  extended.eof_point  = temp(*,3)
  extended.vs_req     = temp(*,4)
  extended.ws_req     = temp(*,5)
  extended.code_size  = temp(*,6)
  extended.code_start = temp(*,7) 

  ; place results in a string array

  strs = ['']

  ; display bootstrap status

  strs = [[strs],'BOOTSTRAP STATUS REPORT' ]
  strs = [[strs],' ']

  FOR k = 0, 31 DO BEGIN

    IF bsr AND 1 THEN strs = [[strs],statuses(k)]

    bsr = ISHFT(bsr,-1)

  ENDFOR

  strs = [[strs],' ']

  ; check any extended processes

  list = WHERE ( extended.patched NE 5, count)

  IF count EQ 0 THEN BEGIN

    strs = [[strs],'EXTENDED MODULE LIST EMPTY']
    strs = [[strs],' ']

  ENDIF ELSE BEGIN

    strs = [[strs],'EXTENDED PROCESS INFORMATION']
    strs = [[strs],' ']
    strs = [[strs], STRING(FORMAT='(A20)', 'MODULE') +      $
                    STRING(FORMAT='(A10)', 'CD SOURCE') +   $
                    STRING(FORMAT='(A11)', 'CD CHSUM')  +   $
                    STRING(FORMAT='(A10)', 'ENTRY OFF') +   $
                    STRING(FORMAT='(A10)', 'VS REQ.') +     $
                    STRING(FORMAT='(A10)', 'WS REQ.') +     $
                    STRING(FORMAT='(A10)', 'CODE SIZE') +   $
                    STRING(FORMAT='(A11)', 'CODE STRT') ]

    FOR k = 0, count-1 DO BEGIN

      p = list(k)

      ; calculate parameter checksum

      parm_checksum = p + extended.ws_req(p) + extended.vs_req(p) + extended.eof_point(p) + $
                          extended.code_size(p)

      ; calculate code checksum

      code_checksum = 0
      FOR c = (extended.code_start(p) + '28C4'X)/4, (extended.code_start(p) + '28C4'X + extended.code_size(p))/4 - 1 DO $
         code_checksum = code_checksum + mem(c)

        IF code_checksum EQ active.c_check(p) AND parm_checksum EQ active.p_check(p) THEN BEGIN
  
          strs = [[strs], STRING(FORMAT='(A20)',modules(p)) +                     $
                          STRING(FORMAT='(A10)',sources(extended.patched(p))) +   $
                          STRING(FORMAT='(A11)',longhex(extended.c_check(p))) +   $
                          STRING(FORMAT='(I10)',extended.eof_point(p)) +          $ 
                          STRING(FORMAT='(I10)',extended.vs_req(p)) +             $
                          STRING(FORMAT='(I10)',extended.ws_req(p)) +             $
                          STRING(FORMAT='(I10)',extended.code_size(p)) +          $
                          STRING(FORMAT='(A11)',longhex(extended.code_start(p) + '800028C4'X)) ]

        ENDIF ELSE BEGIN

          strs = [[strs], STRING(FORMAT='(A20)',modules(p)) +                     $
                          STRING(FORMAT='(A10)',sources(active.patched(p))) +     $
                          STRING(FORMAT='(A11)',longhex(extended.c_check(p))) +   $
                          STRING(FORMAT='(A11)',longhex(extended.p_check(p))) +   $
                          ' CHECKSUM FAILED' ]

        ENDELSE

    ENDFOR

  ENDELSE

  strs = [[strs],'ACTIVE PROCESS INFORMATION']
  strs = [[strs],' ']
  strs = [[strs], STRING(FORMAT='(A20)', 'MODULE') +     $
                  STRING(FORMAT='(A10)', 'CD SOURCE') +  $
                  STRING(FORMAT='(A11)', 'CD CHSUM') +   $
                  STRING(FORMAT='(A10)', 'ENTRY OFF') +  $
                  STRING(FORMAT='(A10)', 'VS REQ.') +    $
                  STRING(FORMAT='(A10)', 'WS REQ.') +    $
                  STRING(FORMAT='(A10)', 'CODE SIZE') +  $
                  STRING(FORMAT='(A11)', 'CODE STRT') ]

  FOR p = 0, 31 DO BEGIN

    ; calculate parameter checksum

    parm_checksum = p + active.ws_req(p) + active.vs_req(p) + active.eof_point(p) + $
                        active.code_size(p)

    ; calculate code checksum

    code_checksum = 0
    FOR c = (active.code_start(p) + '28C4'X)/4, (active.code_start(p) + '28C4'X + active.code_size(p))/4 - 1 DO $
       code_checksum = code_checksum + mem(c)

    IF code_checksum EQ active.c_check(p) AND parm_checksum EQ active.p_check(p) THEN BEGIN

      strs = [[strs], STRING(FORMAT='(A20)',modules(p)) +           $
              STRING(FORMAT='(A10)',sources(active.patched(p))) +   $
              STRING(FORMAT='(A11)',longhex(active.c_check(p))) +   $
              STRING(FORMAT='(I10)',active.eof_point(p)) +          $ 
              STRING(FORMAT='(I10)',active.vs_req(p)) +             $
              STRING(FORMAT='(I10)',active.ws_req(p)) +             $
              STRING(FORMAT='(I10)',active.code_size(p)) +          $
              STRING(FORMAT='(A11)',longhex(active.code_start(p) + '800028C4'X)) ]

    ENDIF ELSE BEGIN

      strs = [[strs], STRING(FORMAT='(A20)',modules(p)) +           $
              STRING(FORMAT='(A10)',sources(active.patched(p))) +   $
              STRING(FORMAT='(A11)',longhex(active.c_check(p))) +   $
              STRING(FORMAT='(A11)',longhex(active.p_check(p))) +   $
              ' CHECKSUM FAILED' ]

    ENDELSE

  ENDFOR
  
  ; get current time

  get_utc, utc, /ECS

  ; display string array

  cp_dsp_strarr, strs, title='BOOTSTRAP REPORT : ' + utc, GROUP=group

END