#!/bin/ksh
# **********************************************
# *                                            *
# *    Firmware Upgrade of SIGMET PCI Cards    *
# *                                            *
# **********************************************

# Script to upgrade (flash) the FPGA code in the SIGMET PCI cards, as
# well as in hardware that might be attached to them.
#
JAMDIR="${IRIS_BIN}rda"

DEVDIR="/dev/rda"
PROC_NODEINFO="/proc/driver/rda/nodeinfo"
PROC_VERSION="/proc/driver/rda/version"
PROC_RECONFIG="/proc/driver/rda/reconfig"
PROC_CONSPACE="/proc/driver/rda/configspace"

PROGRAMMINGNOW="false"
trap ' if [ "${PROGRAMMINGNOW}" = "true" ] ; then
  echo "------------------------- CAUTION -------------------------" ; \
  echo "You have interrupted the normal operation of the flash upgrade" ; \
  echo "procedure for SIGMET PCI cards and hardware.   An interrupted" ; \
  echo "programming sequence could leave your boards unusable after the" ; \
  echo "next PC reboot.  Please insure that programming steps are always" ; \
  echo "allowed to run to completion." ;\
    fi ; exit 1' INT ;

# ------------------------------
# Process command line options
#
ARGLIST=""
PROGRAM="false"

if [ "$1" = "" ] ; then HELP="true" ; else HELP="false" ; fi

while [ ! "$1" = "" ] ; do
  ARG="$1" ; shift

  if [ "${ARG#-}" = "${ARG}" ] ; then
    ARGLIST="${ARGLIST} ${ARG}"

  else
    if   [ "${ARG}" = "-help"    ] ; then
      HELP="true"
    elif [ "${ARG}" = "-program" ] ; then
      PROGRAM="true"
    else
      echo "Unknown option: '${ARG}'" ; HELP="true"
    fi
  fi
done

if [ "${HELP}" = "true" ] ; then
  echo "rdaflash -program [rvp8rx-N] [rvp8ifd-N] [rvp8tx-N] [io62-N] [io62cp-N]"
  exit 0
fi

# ------------------------------
# Run through each of the args
#
if [ ".${ARGLIST}" = "." ] ; then exit 0 ; fi

# Restore volatile PCI registers (just in case), and verify that none
# of the RDA boards are being used right now.  It would be a bad idea
# to reflash a PCI board that is actively inuse.
#
rdasys reconfig ; rdasys testbusy
if [ "$?" = "0" ] ; then
  echo "Sorry, some of the PCI cards are still inuse.  Please try again"
  echo "  after quitting all applications (RVP8, RCP8, etc) that use any"
  echo "  of this hardware."
  exit 1 
fi

for ARG in ${ARGLIST} ; do
  # Convert programming device name to actual PCI hardware name, and
  # number of the JTAG chain required to access it.
  #
  BASENAME="${ARG%-*}" ; UNIT="${ARG#*-}"

  if [ ".${BASENAME}" = "."       -o ".${UNIT}" = "."       -o \
       ".${BASENAME}" = ".${ARG}" -o ".${UNIT}" = ".${ARG}" ] ; then
    echo "Bad device name format: '${ARG}'" ; exit 1
  else
    if   [ "${BASENAME}" = "rvp8rx"  ] ; then
      PCINAME="rvp8rx-${UNIT}" ; JTAG="0" ;
    elif [ "${BASENAME}" = "rvp8ifd" ] ; then
      PCINAME="rvp8rx-${UNIT}" ; JTAG="1" ;
    elif [ "${BASENAME}" = "rvp8tx"  ] ; then
      PCINAME="rvp8tx-${UNIT}" ; JTAG="0" ;
    elif [ "${BASENAME}" = "io62"    ] ; then
      PCINAME="io62-${UNIT}"   ; JTAG="0" ;
    elif [ "${BASENAME}" = "io62cp"  ] ; then
      PCINAME="io62-${UNIT}"   ; JTAG="1" ;
    else
      echo "Unrecognized argument: '${ARG}'" ; exit 1
    fi
  fi
  # Verify that the PCI device exists, and that the associated
  # programming file can be found either in the current directory or
  # in the standard release location.
  #
  if [ ! -r "${DEVDIR}/${PCINAME}" ] ; then
    echo "Could not open hardware device: ${DEVDIR}/${PCINAME}" ; exit 1
  else
    # Figure out which hardware version of PCI card we're talking to.
    #
    CONLINE="`cat ${PROC_CONSPACE} | grep ${PCINAME}`"
    REVLETTER="${CONLINE##*Rev.}" ; REVLETTER="${REVLETTER%% *}"
    if [ "${#REVLETTER}" != "1" ] ; then
      echo "Could not deduce the board version for ${PCINAME}" ; exit 1 ;
    fi

    # Make the name of the JAM file that has the programming info for
    # the targeted device.  We generally just refer to the basename,
    # but in some cases we have to check the board version to know the
    # proper file name.
    #
    JAMFILE="${BASENAME}.jbc"

    if [ "${BASENAME}" = "rvp8rx" ] ; then
      if [ "${REVLETTER}" = "A" -o "${REVLETTER}" = "B" ] ; then
	JAMFILE="rvp8rx-ab.jbc"
      fi
    fi

    # Verify that the programming file exists and is readable.
    #
    JAMPATH=""    
    if   [ -r "./${JAMFILE}"         ] ; then JAMPATH="./${JAMFILE}"
    elif [ -r "${JAMDIR}/${JAMFILE}" ] ; then JAMPATH="${JAMDIR}/${JAMFILE}"
    fi

    if [ ".${JAMPATH}" = "." ] ; then
      echo "Could not open programming file: ${JAMFILE}" ; exit 1
    else
      # If we are reprogramming a backpanel card, then setup the IO62
      # to access the remote JTAG chain.  CAUTION: This uses constants
      # that are properly defined only in io62.h.
      #
      if [ "${BASENAME}" = "io62cp" ] ; then
        rdaport ${PCINAME} 0  00B9 > /dev/null ; sleep 0.5 # Reset IO62
        rdaport ${PCINAME} 10 6FF7 > /dev/null             # RS422 Tx/Rx
        rdaport ${PCINAME} 20 0007 > /dev/null             # Enable backpanel I/O
      fi
      # Try to verify what's programmed there already.  This verifies
      # both the programming file and the hardware JTAG chain.
      #
      echo "===============  Flashing device ${ARG} ==============="
      echo "Verifying device (may take several minutes)..."

      EXITSTR="`jamplayer ${JAMPATH} -# -averify -t${PCINAME} -q${JTAG} 2>/dev/null |
        grep '^Exit code'`"
      EXITNUM="`echo ${EXITSTR} | sed 's/^Exit code = //' | sed 's/[^0-9].*//'`"

      if   [ "${EXITNUM}" = "0" ] ; then  # Success
        echo "The firmware residing on the board is up to date."

      elif [ "${EXITNUM}" = "6" ] ; then  # Unrecognized device
        echo "JTAG chain does not match the programming file."
	echo "Please check board jumpers and connecting cables."
	exit 1

      elif [ "${EXITNUM}" = "11" ] ; then  # Device verify failure
        echo "The board's firmware does not match the latest release."

        # If we get a verification error, that means that the JTAG
        # chain is working properly, and the device really does need
        # to be reprogrammed.
        #
	if [ "${PROGRAM}" = "true" ] ; then
	  PROGRAMMINGNOW="true"

          echo "\nReprogramming device (may take several minutes)..."
          jamplayer ${JAMPATH} -# -aprogram -dDO_VERIFY=0 -t${PCINAME} -q${JTAG} 2>/dev/null

          echo "Verifying programming (may take several minutes)..."

          EXITSTR="`jamplayer ${JAMPATH} -# -averify -t${PCINAME} -q${JTAG} 2>/dev/null |
            grep '^Exit code'`"
          EXITNUM="`echo ${EXITSTR} | sed 's/^Exit code = //' | sed 's/[^0-9].*//'`"

	  PROGRAMMINGNOW="false"

          if   [ "${EXITNUM}" = "0" ] ; then  # Success
	    echo "Device programming was successful.  Rebooting into the"
	    echo "  code that was just installed."
            echo ""
	    if [ "${JTAG}" = "0" ] ; then
	      rdaport -bootPage ${PCINAME} 0        ; sleep 2.0
	      rdasys reconfig                       ; sleep 0.5
              rdaport ${PCINAME}  0  B9 > /dev/null ; sleep 0.5

	    elif [ "${BASENAME}" = "rvp8ifd" ] ; then
	      rdaport ${PCINAME}  7 102 > /dev/null
	      rdaport ${PCINAME}  7  20 > /dev/null ; sleep 0.5
	    fi
          else
            echo "Unexpected error: ${EXITSTR}"
	    echo "Device programming failed.  The card is (most likely) still"
	    echo "  running properly with its original firmware, but it would"
	    echo "  be non-operational after a PC reboot.  This is potentially"
	    echo "  a serious problem.  Please try reprogramming IMMEDIATELY."
	    exit 1
          fi
	fi
      else
        echo "Unknown verification: ${EXITSTR}" ; exit 1
      fi
    fi
  fi
done
