# genmen, the brains of the uboot boot.scr generator
#
# Copyright 2013 Red Hat, Inc.  All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

PATH=/sbin:/bin:$PATH

. /etc/sysconfig/uboot

: ${UBOOT_DIR:="/boot"}
: ${UBOOT_KLIST:="$UBOOT_DIR/klist.txt"}

###############################
cd /boot

KCOUNT=0
declare -A kmap

# for k in `ls vmlinuz* | sed s/vmlinuz-//g | sort`; do
for k in `tac $UBOOT_KLIST`; do
  if [ ! -f vmlinuz-$k ] || [ ! -f initramfs-$k.img ]; then
    echo "$UBOOT_KLIST showed $k but an associated vmlinuz or initramfs does not exist in /boot. Exiting."
    exit 1
  fi
  KCOUNT=$[ $KCOUNT + 1 ]
  KLIST="$KLIST $k"

  case $k in
    *armv7l|*armv7hl) ktype=unified; ;;
    *) ktype="`echo $k | sed 's/.*armv7[hl]*.//'`" ;;
  esac

  kmap[${KCOUNT}]=$k
  kmap[${KCOUNT}_type]=$ktype

  FDTCOUNT=0
  if [ -d dtb-$k ]; then
    for d in `ls dtb-$k/* | sed 's,.*/,,'`; do
      FDTCOUNT=$[ $FDTCOUNT + 1 ]
      kmap[${KCOUNT}_${FDTCOUNT}]=$d
    done
  else
    echo "Did not find dtb directory in /boot/dtb-$k, exiting."
    exit 1
  fi
  kmap[${KCOUNT}_fdtcount]=$FDTCOUNT
done

echo "k_count='`seq -s \  1 $KCOUNT`'"
for k in `seq 1 $KCOUNT`; do
  echo "kv${k}=${kmap[$k]}"
  echo "ka${k}=${kmap[${k}_type]}"
  echo "kfdtc${k}=\"`seq -s \  1 ${kmap[${k}_fdtcount]}`\""
  for d in `seq 1 ${kmap[${k}_fdtcount]}`; do
    echo "k${k}_${d}=${kmap[${k}_${d}]}"
  done
done

# u_k # (# corresponding to bottom of klist.txt)
# k_count # (number of kernels)
# kv# (name of kernel#)
# ka# arch (name of kernel architecture)
# kfdtc# # (number of dtbs for this kernel)
# k#_# dtbfile (name of each dtbfile)

for k in `seq 1 $KCOUNT`; do
  echo "setenv k$k \"u_k=$k; have_k=\"\"; have_i=\"\"; have_d=\"\"; run kl_picked\""
done

cat << EOF

#Infra for klist command
setenv klist "run kl_start kl_enum kl_default kl_end"
setenv kl_start echo\; echo Kernel List\; echo -----------
setenv kl_enum for i in \\\$k_count\;do setenv catin ka\\\$i\;run catcat \;run kl_enum2 \;done
setenv kl_enum2 setenv tmpktype \\\$catout\;setenv catin kv\\\$i\;run catcat \;echo k\\\$i: \\\$catout for \\\$tmpktype
setenv kl_default echo (Currently selected: k\\\$u_k: \\\$u_kernel)\; echo
setenv kl_end echo Type \\\\\'run kX\\\\\' where X is the kernel number to use.

#Run each time a new kernel is selected
setenv kl_picked setenv catin kv\\\$u_k\;run catcat \;setenv u_kernel \\\$catout\;run kl_picked_2
setenv kl_picked_2 echo Using kernel k\\\$u_k (\\\$u_kernel).

#Infra for dtblist command
setenv dtblist run dtb_start dtb_head dtb_enum dtb_default dtb_end
setenv dtb_start echo\; echo "Device Tree Blob (DTB) list"\; echo
setenv dtb_head echo Kernel \\\$u_kernel has the following dtbs available:
setenv dtb_enum setenv catin kfdtc\\\$u_k\;run catcat \;for i in \\\$catout\;do run dtb_enum2 \;done
setenv dtb_enum2 setenv catin k\\\${u_k}_\\\$i\; run catcat \; run dtb_enum3
setenv dtb_enum3 echo dtb\\\$i: \\\$catout\;setenv dtb\\\$i u_dtb=\\\$catout \\\\\; run dtb_chosen
setenv dtb_end echo Type \\\\\'run dtbX\\\\\' where X is the dtb number to use.
setenv dtb_default echo (Currently selected: \\\$u_dtb)\; echo
setenv dtb_chosen echo DTB selected. Type \\\\\'boot\\\\\' to start.

#Set a default kernel
setenv set_u_k 'if test -n \$u_dtb \;then run set_u_k2 ;else run set_u_k_nodtb ;fi'
setenv set_u_k2 'u_kernel="";for on_k in \$k_count; do run set_u_k3 ;done; run set_u_k8'
setenv set_u_k3 'if test -n \$u_kernel\;then run true ;else run set_u_k4 ;run set_u_k5 ;fi'
setenv set_u_k4 'setenv catin kfdtc\$on_k ;run catcat'
setenv set_u_k5 'for on_d in \$catout; do run set_u_k6 ;run set_u_k7 ;done'
setenv set_u_k6 'setenv catin k\${on_k}_\${on_d}; run catcat'
setenv set_u_k7 'if test \$catout = \$u_dtb ;then run k\$on_k ;fi'
setenv set_u_k8 'if test -n \$u_kernel;then run true;else echo "No kernel provides dtb named \$u_dtb";run false;fi'
setenv set_u_k_nodtb 'echo "No value for u_dtb.  Use klist and dtblist to select."; run help'

#Infra for clist command
setenv clist "run cl_start cl_enum cl_end"
setenv cl_start echo\; echo Board Configuration List\; echo ------------------------
setenv cl_enum for i in \\\$c_count\;do setenv catin ca\\\$i\;run catcat \;echo c\\\$i: \\\$catout \;done
setenv cl_end echo Type \\\\\'run cX\\\\\' where X is the board configuration number to use.

EOF
