#
# This script can be run from U-Boot with the "source" command to
# deploy the BlueBox image to NOR flash properly using one of the below
# options:
# - SD card (FAT32 partitioned)
# - USB Stick (FAT32 partitioned)
# - TFTP
#
# DANGER! NO WAY BACK ONCE THIS SCRIPT RUNS!
#
# <Heinz.Wrobel@nxp.com>
#
# SD-Card/USB stick preparation
#       First partition must be FAT32 and must contain the compiled
#       script image (.img and/or .itb) and
#       the correct image for the box in question:
#       fsl-image-blueboxbootflash-<platform>.flashimage
# TFTP preparation
#       TFTP exported directory must contain the compiled script image
#       (.img and/or .itb) and
#       fsl-image-blueboxbootflash-<platform>.flashimage
#
# where <platform> can be:
#       - ls2084abbmini
#       - ls2084abluebox
#       - ls2080abluebox
#
# Preferred ITB script usage in U-Boot
#
# Script loading using:
# - MMC
#       mmc rescan
#       fatload mmc 0:1 90000000 bbdeployimage.itb
# - USB
#       usb reset
#       fatload usb 0:1 90000000 bbdeployimage.itb
# - TFTP
#       tftp 90000000 bbdeployimage.itb
#
# Script sourcing
#       source 90000000:ls2deployflash
#
#----------------------------------------------------------------------
# Script configuration area
#----------------------------------------------------------------------
# nv env variables would hide hush variables
setenv file
setenv neededfilesize
setenv shellscript
shellscript='bbdeployimage.sh'

# We support two banks, and split areas in each for Power Architecture.
# If two banks or split areas are not needed, they can be set to the
# same text value respectively without affecting the result
# First address always must be the LOWEST!
#----------------------------------------------------------------------
echo ""
echo "*** BlueBox update script for LS208xA NOR Flash ***"
echo ""

#----------------------------------------------------------------------
# We determine the image file we need. This can be either
# - BB Classic with LS2080A
# - BB Classic with LS2084A
# - BB Mini with LS2084A

flashtype="<unknownflashtype>"
file="<unknownimagefile>"

neededfilesize=08000000     # 128MiB
setenv switchtobank0 ""
saddr_0_1=a0000000
daddr_0_1=580000000
ssize_0_1=04000000
saddr_0_2=a0000000
daddr_0_2=580000000
ssize_0_2=04000000
setenv switchtobank4 ""
saddr_4_1=a4000000
daddr_4_1=584000000
ssize_4_1=04000000
saddr_4_2=a4000000
daddr_4_2=584000000
ssize_4_2=04000000

#----------------------------------------------------------------------
if itest.b *0x520000000 -eq 0x41; then
        # BB Mini
        echo "This script is running on BlueBox Mini with LS2084A ..."
        flashtype='NOR'
        file='fsl-image-blueboxbootflash-ls2084abbmini.flashimage'
else
        # BB Classic
        if itest.w *0x01e000a6 -eq 0x8709; then
                echo "This script is running on BlueBox Classic with LS2084A ..."
                flashtype='NOR'
                file='fsl-image-blueboxbootflash-ls2084abluebox.flashimage'
        fi
        if itest.w *0x01e000a6 -eq 0x8701; then
                echo "This script is running on BlueBox Classic with LS2080A ..."
                flashtype='NOR'
                file='fsl-image-blueboxbootflash-ls2080abluebox.flashimage'
        fi
fi

echo "We will search for the image $file ..."

#----------------------------------------------------------------------
# Check if setexpr is supported, which means possibly faster flash
# updates.
# Note that the weird indent is intentional as there appear to be
# length limitations for continued lines in U-Boot. By reducing the
# indent on complex setenv, we keep content length low.
# Note that depending on the U-Boot version, 'test' may only compare
# decimal numbers properly, which is why we do a weird test for 0.
setenv cmd_flashnorblock '
echo "Checking 0x$da:" "\\\\c";
if cmp.b $sa $da $ss; then
  ok=1;
else
  ok=0;
  if test $verbose -gt 0; then echo "Erasing NOR..."; fi; if test 1$scripttest -lt 11; then erase $da +$ss; fi;
  if test $verbose -gt 0; then echo "Flashing NOR..."; fi; if test 1$scripttest -lt 11; then cp.b $sa $da $ss; fi;
  if test $verbose -gt 0; then echo "Comparing NOR to image..."; fi; if cmp.b $sa $da $ss; then ok=1; fi;
fi;
'
if setexpr x 0 + 1; then
        echo "setexpr command is available. Efficient flash method used ..."
        setenv cmd_flashnorrange '
verbose=0;
breakwhile=0;
ss=80000;
echo "Erasing/Flashing/Comparing NOR in 0x$ss sized blocks...";
offset=0;
size=$ssize;
while test 1$size -ne 10 && test $breakwhile -eq 0; do
  setexpr x $saddr + $offset;
  sa=$x;
  setexpr x $daddr + $offset;
  da=$x;
  run cmd_flashnorblock;
  if test $ok -eq 0; then
    echo "Failure at offset 0x$offset! ABORTING ...";
    breakwhile=1;
  fi;
  setexpr x $offset + $ss;
  offset=$x;
  setexpr x $size - $ss;
  size=$x;
done;'
else
        echo "setexpr command is unavailable. Standard flash method used ..."
        setenv cmd_flashnorrange '
verbose=1;
ss=$ssize;
sa=$saddr;
da=$daddr;
run cmd_flashnorblock;'
fi
setenv cmd_flashqspirange '
sf update $saddr $daddr $ssize'
setenv cmd_flashNORprobe ''
setenv cmd_flashQSPIprobe 'sf probe 0'
setenv cmd_flashNORbank '
echo "Unprotecting NOR..."; protect off $daddr +$ssize;
run cmd_flashnorrange'
setenv cmd_flashQSPIbank '
echo "Unprotecting QSPI..."; sf protect unlock $daddr +$ssize;
run cmd_flashqspirange'

#----------------------------------------------------------------------
# We prepare for the full flash even with a partial image to have
# always a well defined result by prefilling the memory!
mw.b $saddr_0_1 ff $neededfilesize

# Now load the image file and check if it is the right size
setenv ok
ok=0

# Start checking the image file on the SD card
echo "Searching for image on SD card ..."
mmc rescan
mmc info
echo "Checking first partition (FAT) ..."
if fatload mmc 0:1 $saddr_0_1 $file; then
	filesrc='cd /run/media/mmcblk0p1'
        ok=1
else
	echo "Checking second partition (ext2) ..."
        if ext2load mmc 0:2 $saddr_0_1 boot/$file; then
	        filesrc='cd /run/media/mmcblk0p2/boot'
                ok=1
        fi
fi

if test $ok -eq 0; then
        echo "Searching for image on USB stick ..."
        # Fall back to USB if no file is available on SDHC
        # If this script didn't come from USB, USB is not started
        # and this will fail quickly
        if usb storage; then
                echo "Loading from USB (This may take about 60 seconds ...)"
                if fatload usb 0:1 $saddr_0_1 $file; then
			filesrc='cd /run/media/sdb1'
                        ok=1
                fi
        fi
        if test $ok -eq 0; then
                echo "Searching for image using TFTP ..."
                ping $serverip
                if tftp $saddr_0_1 $file; then
			filesrc='<get file via tftp from TFTP server>'
                        ok=1
                fi
        fi
fi

if test $ok -gt 0; then
        if test 0x$filesize -eq 0x$neededfilesize; then
                ok=1
        else
                echo "Loaded ${flashtype} Flash Image is not exactly of $neededfilesize size! ABORTING ..."
                ok=0
        fi
fi

setenv bank
setenv saddr
setenv daddr
setenv ssize
setenv sa
setenv da
setenv ss
for bank in 0 4; do
	setenv x "run switchtobank${bank}"; run x
	setenv x "run cmd_flash${flashtype}probe"; run x
        if test $ok -gt 0; then
                # Trick to do dynamic U-Boot variable expansion
                setenv x "saddr1=\$saddr_${bank}_1 daddr1=\$daddr_${bank}_1 ssize1=\$ssize_${bank}_1"; run x
                setenv x "saddr2=\$saddr_${bank}_2 daddr2=\$daddr_${bank}_2 ssize2=\$ssize_${bank}_2"; run x
                echo ""
                echo "Checking if ${flashtype} Bank ${bank} needs an update..."
                if test "${flashtype}" = "NOR" && cmp.b $saddr1 $daddr1 $ssize1 && cmp.b $saddr2 $daddr2 $ssize2; then
                        ok=1
                else
                        echo "*** Updating ${flashtype} Bank ${bank} ***"
                        saddr=$saddr1
                        daddr=$daddr1
                        ssize=$ssize1
                        setenv x "run cmd_flash${flashtype}bank"; run x
                        echo "Protecting RCW in ${flashtype}..."; protect on $daddr +1;
                        if test $ok -gt 0 && test $saddr1 -ne $saddr2; then
                                saddr=$saddr2
                                daddr=$daddr2
                                ssize=$ssize2
				setenv x "run cmd_flash${flashtype}bank"; run x
                        fi
                fi

                if test $ok -gt 0; then
                        echo "*** Update for ${flashtype} Bank ${bank} complete ***"
                else
                        echo ""
                        echo "*** Update FAILED for ${flashtype} Bank ${bank} ***"
                fi
                echo ""
        fi
done
setenv x

if test $ok -gt 0; then
        echo ""
        echo ""
        echo "The NOR flash is properly initialized now for the BlueBox!"
        echo ""
        echo ""
        echo ""
        echo "****************************************************************"
        echo "Next step would be to prep the SSD properly."
        echo 'Please "reset" now to reboot the board, abort into the command'
        echo 'line of U-Boot with a keypress, and "run boot_from_flash".'
        echo "Log into the ${flashtype} flash Linux as \"root\"."
        echo "Then"
        echo "    $filesrc"
        echo "and finally"
        echo "    ./$shellscript"
        echo "****************************************************************"
else
        echo ""
        echo ""
        echo "****************************************************************"
        echo "****                    F A I L U R E                       ****"
        echo "****************************************************************"
        echo ""
        echo ""
        echo "Please retry/fix until at least one bank is properly flashed!"
        echo "DO NOT RESET WITHOUT A FUNCTIONAL BANK or you need a JTAG"
        echo "debugger to recover the board..."
fi

