#!/bin/sh

set -e

script_dir=$(cd "$(dirname "$0")" && pwd)
TMP_DIR=""

die() {
   echo "$@" >&2
   exit 1
}

cleanup() {
   if [ -d "${TMP_DIR}" ]; then
      rm -rf "${TMP_DIR}"
   fi
}

usage() {
cat <<EOF
Usage:
$(basename "$0"): <gpio_num>

	Creates an SD card image which programs the OTP on a Pi 4B or Pi 400
	to select a GPIO on the 40-pin header for use as the rpiboot GPIO.
	Once programmed, if this GPIO is pulled to ground at power on, the
	SoC bootrom will boot into rpiboot provisioning mode.

	This setting _permanently_ modifies the device configuration - it cannot
	be undone or changed, ever.

	The SD image will be written to images-2711/pi4-program-rpiboot-gpioN.zip,
	where N is the number of the chosen GPIO, and can be flashed using
	Raspberry Pi Imager to a spare SD card. As with programming the bootloader
	EEPROM, insert the card in the Raspberry Pi, power on and wait for the
	green LED to flash.

	gpio_num: Select the rpiboot BCM GPIO number from 2,4,5,6,7 or 8.

	See imager/README-pi4-rpiboot-gpio-sd.md for dependencies and image details.
EOF
    exit 1
}

trap cleanup EXIT

build_image()
{
   chip="${1}"
   gpio="${2}"
   img="pi4-program-rpiboot-gpio${gpio}"
   zip="${img}.zip"
   img="${img}.img"
   partition_start=2048
   partition_size=524288
   temp_disk_img="temp.img"
   temp_partition_img="fat.img"

   TMP_DIR="$(mktemp -d)"
   (
      mkdir "${TMP_DIR}/files"
      cd "${TMP_DIR}/files"
      cp "${script_dir}/../firmware-${chip}/latest/recovery.bin" .
   cat <<EOF > config.txt
uart_2ndstage=1
recovery_wait=1
program_rpiboot_gpio=${gpio}
EOF
      echo "Generated config.txt file"
      cat config.txt
      cd "${TMP_DIR}"
      dd if=/dev/zero bs=1M count=258 of="${temp_disk_img}" > /dev/null 2>&1
      "${SFDISK}" "${temp_disk_img}" <<EOF
label: dos
label-id: 0x0a7b5ac5
device: ${temp_disk_img}
unit: sectors

./test.img1 : start=        ${partition_start}, size=       ${partition_size}, type=c
EOF
      file "${temp_disk_img}"
      dd if=/dev/zero bs=512 count="${partition_size}" of="${temp_partition_img}" > /dev/null 2>&1
      "${MKFS_FAT}" -F 32 -s 1 "${temp_partition_img}" > /dev/null
      "${MCOPY}" -i "${temp_partition_img}" -v files/* ::
      dd if="${temp_partition_img}" of="${temp_disk_img}" bs=512 seek="${partition_start}" conv=notrunc > /dev/null 2>&1
   )
   image_dir="images-${chip}"
   mkdir -p "${image_dir}"
   mv "${TMP_DIR}/${temp_disk_img}" "${image_dir}/${img}"
   file "${image_dir}/${img}"
   cd "${image_dir}"
   "${ZIP}" "${zip}" "${img}"
   cd ..
   rm "${image_dir}/${img}"
   echo "Wrote $(pwd)/${image_dir}/${zip}"
}


[ -n "${1}" ] || usage
gpio_num="$1"

case "${gpio_num}" in
   	2)
		;;
	4)
		;;
	5)
		;;
	6)
		;;
	7)
		;;
	8)
		;;
        *)
		echo "GPIO ${gpio_num} is not supported"
		echo
  	  usage
	  	;;
esac

if ! SFDISK=$(command -v sfdisk); then
   die "sfdisk not found: Try installing the util-linux package"
fi

if ! MKFS_FAT=$(command -v mkfs.fat); then
   die "mkfs.fat not found: Try installing the dosfstools package"
fi

if ! MCOPY=$(command -v mcopy); then
   die "mcopy not found: Try installing the mtools package"
fi

if ! ZIP=$(command -v zip); then
   die "zip not found: Try installing the zip package"
fi

build_image 2711 "${gpio_num}"
