# U-Boot: sunXi
# Contributor: Isaac David <isacdaavid@at@isacdaavid@dot@info>
# Contributor: André Silva <emulatorman@hyperbola.info>
# Contributor: Timothy Redaelli <timothy.redaelli@gmail.com>
# Contributor: Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
# Maintainer: Parabola Hackers <dev@lists.parabola.nu>

# To add a new board (that uses an Allwinner System On a Chip) you need:
# - The package name. Example: uboot4extlinux-a20-olinuxino_micro
# - The u-boot configuration. Example: A20-OLinuXino_MICRO_defconfig
# - The name of the board(s). Example: A20 OLinuXino Micro
#   A single package / u-boot configuration sometimes support multiple
#   boards and the configuration name doesn't always have the boards names
#   in it. Example: uboot4extlinux-am335x_bone supports various BeagleBones,
#   the AM335x GP EVM and the EVM SK all in one u-boot binary and package.
# - If relevant, the packages it replaces, if there are older u-boot packages
#   also supporting that board. Example:uboot-a20-olinuxino-micro
#
# Ideally we'd like to enable people to only add these 4 variables in this
# package to add a new board. These 4 variables could go in something like
# a CVS file that is parsed, but that would require to be able to dynamically
# define packages, but even if eval package_{$_pkgname}() { [...] } works,
# it doesn't make that package function visible to makepkg.
#
# Because of that, contributors wanting to add new boards will have to search
# for example of the information mentioned above and add it in the PKGBUILD
# for their boards.
#
# After adding a new board in this PKGBUILD, to get the board officially
# supported by Parabola.you also need to create a page for it in the
# Parabola wiki for that board and update the ARM installation guide to
# point to it when relevant. Examples of that are available for other
# boards in the ARM installation guide.

_upstream_name=u-boot-libre
pkgbase=uboot4extlinux-sunxi
pkgname=("${pkgbase}"
         'uboot4extlinux-a10-olinuxino-lime'
         'uboot4extlinux-a10s-olinuxino-m'
         'uboot4extlinux-a13-olinuxino'
         'uboot4extlinux-a13-olinuxinom'
         'uboot4extlinux-a20-olinuxino-lime'
         'uboot4extlinux-a20-olinuxino-lime2'
         'uboot4extlinux-a20-olinuxino-lime2-emmc'
         'uboot4extlinux-a20-olinuxino_micro'
         'uboot4extlinux-bananapi'
         'uboot4extlinux-bananapro'
         'uboot4extlinux-chip'
         'uboot4extlinux-cubieboard'
         'uboot4extlinux-cubieboard2'
         'uboot4extlinux-cubietruck'
         'uboot4extlinux-linksprite_pcduino'
         'uboot4extlinux-linksprite_pcduino3'
         'uboot4extlinux-linksprite_pcduino3_nano'
         'uboot4extlinux-orangepi_2'
         'uboot4extlinux-orangepi_one'
         'uboot4extlinux-orangepi_pc'
         'uboot4extlinux-orangepi_plus')

_uboot_ver=2022.04 # version of the upstream u-boot source code
_ubootlibre_rev=r1 # revision of the u-boot-libre deblob script

pkgver="${_uboot_ver}"
pkgrel="${_ubootlibre_rev}.parabola3"

arch=('armv7h' 'i686' 'x86_64')
url="https://libreboot.org/docs/maintain/#resourcesscriptsbuildreleaseu-boot-libre"
license=('GPL')
makedepends=('bc' 'dtc' 'python' 'python-setuptools' 'python2' 'swig')
makedepends_i686+=('arm-none-eabi-gcc')
makedepends_ppc64le+=('arm-none-eabi-gcc')
makedepends_x86_64+=('arm-none-eabi-gcc')

_mirror="https://mirrors.mit.edu/libreboot/" # use a mirror per libreboot's request
source=("${_mirror}/${_upstream_name}/${_uboot_ver}-${_ubootlibre_rev}/${_upstream_name}-${_uboot_ver}-${_ubootlibre_rev}.tar.xz")
source+=('extlinux.conf'
        "${pkgbase}.hook.in"
        'install-uboot4extlinux.sh.in'
        "generate-${pkgbase}-install-text.sh")

# TODO: this checksum doesn't correspond to the one in
#       tests/u-boot-libre.sha512. This means that the tarball is not
#       reproducible yet. According to diffoscope, the only changes so
#       far seems to be some permissions changes:
#       │ -drwxr-xr-x [...]     0 1969-12-31 23:00:00.000000 u-boot-libre-2021.07-r1/
#       │ +drwxrwxr-x [...]     0 1969-12-31 23:00:00.000000 u-boot-libre-2021.07-r1/
#       │ --rw-r--r-- [...] 16576 1969-12-31 23:00:00.000000 u-boot-libre-2021.07-r1/.azure-pipelines.yml
#       │ +-rw-rw-r-- [...] 16576 1969-12-31 23:00:00.000000 u-boot-libre-2021.07-r1/.azure-pipelines.yml
#       I've not checked if some files were added or not but at least it
#       shows only diffs like the one above, and it doesn't show any file
#       content diff.
# TODO: Check the signatures of the released files, not just the content
# TODO: We also need to look into drivers/dma/MCD_tasks.c. The debian
#       version of u-boot removes it. It's some data that looks like
#       code, so while there is a valid license, we might lack
#       corresponding source code if it's really some code. The debian
#       commits might have more information about it.
sha512sums=('b816667988210c4f5e0e219fcf633fe0c599ced74568a2924afc8df14bede52ce0c9615ff27eae3ecf194d41a87d04231f099c90beece18028ee5890a3911669')
sha512sums+=('dcbcbc8d196c7dd7db1a8a30dfa8c9ece5d241580bdf593df5fa2de527f0dfea2bb76ff9bfe49fb1e9d631bd1e4b95c828a41cfb38dc2ddc9553e18a54a521f0'
             '766b28c45218746672d3e802c16f2c1283d708b43edf0a42cb569c1cfa6d6d3f318d5da91efcc832303dcc2175ee23528d15891010c187dea4c6828e82596be3'
             '1ecb7b932bb0b097cac2cdfabbf7faa1601a556b49782f68109be07e49bff62d4515d6492ad1c72f471cdc7b4e1c2d8750e3494fcb0fc93108e6e5bd4e82aedb'
             'b0e8b0ec7f742778ffed486cf529d56d550db48354a4251867078fda8e5a28c8938f6c005225042744c1117a6abb3843e632234b8fd73d8bfdd9c590b0165e4c')

# supported boards
_defconfigs=('A10-OLinuXino-Lime_defconfig'
             'A10s-OLinuXino-M_defconfig'
             'A13-OLinuXino_defconfig'
             'A13-OLinuXinoM_defconfig'
             'A20-OLinuXino-Lime_defconfig'
             'A20-OLinuXino-Lime2_defconfig'
             'A20-OLinuXino-Lime2-eMMC_defconfig'
             'A20-OLinuXino_MICRO_defconfig'
             'Bananapi_defconfig'
             'Bananapro_defconfig'
             'CHIP_defconfig'
             'Cubieboard_defconfig'
             'Cubieboard2_defconfig'
             'Cubietruck_defconfig'
             'Linksprite_pcDuino_defconfig'
             'Linksprite_pcDuino3_defconfig'
             'Linksprite_pcDuino3_Nano_defconfig'
             'orangepi_2_defconfig'
             'orangepi_one_defconfig'
             'orangepi_pc_defconfig'
             'orangepi_plus_defconfig')

# Offset at which to install u-boot
u_boot_with_spl_offset=8192

_nr_targets=0
for _defconfig in ${_defconfigs[@]}; do
    _nr_targets=$(expr ${_nr_targets} + 1)
done

_get_target_name()
{
    _defconfig="$1"

    echo ${_defconfig} | \
        sed 's/_defconfig$//' | \
        awk '{print tolower($0)}'
}

_get_target_destdir()
{
    _defconfig="$1"

    _target_name="$(_get_target_name ${_defconfig})"

    echo "build/uboot4extlinux-${_target_name}"
}

_build_uboot_target()
{
    _defconfig="$1"

    _destdir="$(_get_target_destdir ${_defconfig})"
    _target_name="$(_get_target_name ${_defconfig})"

    unset CFLAGS CXXFLAGS LDFLAGS

    local make_vars=( ARCH=arm )
    make ${make_vars[*]} distclean
    make ${make_vars[*]} ${_defconfig}

    make_vars+=( EXTRAVERSION=-${pkgrel} )
    [[ "$CARCH" != armv7h ]] && make_vars+=( CROSS_COMPILE=arm-none-eabi- ) || :
    echo 'CONFIG_IDENT_STRING=" Parabola GNU/Linux-libre"' >> .config
    make ${make_vars[*]}

    echo "==> Installing ${_target_name} to ${_destdir}"
    install -d ${_destdir}
    mv -f u-boot-sunxi-with-spl.bin "${_destdir}"
}

# TODO: We need to fix the timestamps upstream to a valid date
#       (like the first January 1970at 01:00:00 CET) or something derived
#       from the release version somehow. Else we have the build log spammed
#       with errors like that:
#       make: scripts/Makefile.extrawarn: Timestamp out of range;
#             substituting 1970-01-01 00:59:59.999999999
# TODO: While we're at it we could export SOURCE_DATE_SPOCH to try to
#       make the u-boot package reporducible.
prepare()
{
  cd "${srcdir}"/u-boot-v${_uboot_ver}-${_ubootlibre_rev}
  find -print0 | xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}"
}

build()
{
  cd "${srcdir}"/u-boot-v${_uboot_ver}-${_ubootlibre_rev}

  _target_nr=0
  for _defconfig in ${_defconfigs[@]}; do
      _target_nr=$(expr ${_target_nr} + 1)
      _target_name="$(_get_target_name ${_defconfig})"

      echo "==> Building ${_target_name} " \
           "[${_target_nr} of ${_nr_targets} targets]"

      _build_uboot_target "${_defconfig}"
  done
}

_check_uboot_target()
{
    _defconfig="$1"

    _image="$(_get_target_destdir ${_defconfig})/u-boot-sunxi-with-spl.bin"
    _image_size="$(du --bytes --apparent-size ${_image} | awk '{print $1}')"
    _offset="${u_boot_with_spl_offset}"

    _image_end=$(expr ${_image_size} + ${_offset})

    # This test comes from install-uboot4extlinux.sh.in
    if [ ${_image_end} -gt $(expr 1024 \* 1024) ] ; then
        echo "Error: ${_image} is too big:"
        echo "       offset: ${_offset}"
        echo "       size:   ${_image_size}"
        echo "       By default, "\
             "partitioing tools makes the first partition start at 1MiB"
        echo "       Instaling ${_image} "\
             "would overwrite that first partition (if it's present)."

        false # Fail the test
    fi
}

check()
{
  cd "${srcdir}"/u-boot-v${_uboot_ver}-${_ubootlibre_rev}

  _target_nr=0
  for _defconfig in ${_defconfigs[@]}; do
      _target_nr=$(expr ${_target_nr} + 1)
      _target_name="$(_get_target_name ${_defconfig})"

      echo "==> Testing target ${_target_name} " \
           "[${_target_nr} of ${_nr_targets} targets]"
      _check_uboot_target "${_defconfig}"
  done

}

_make_uboot_package()
{
    _pkgname="$1"

    if [ -n "${pkgdir}" ] ; then
        cd "${srcdir}"/u-boot-v${_uboot_ver}-${_ubootlibre_rev}

        # Install the u-boot binary
        install -d "${pkgdir}/usr/lib/u-boot/${_pkgname}/"
        install -Dm644 "build/${_pkgname}/u-boot-sunxi-with-spl.bin" \
                "${pkgdir}/usr/lib/u-boot/${_pkgname}"

        # Install the u-boot installation script
        sed < "${srcdir}/install-uboot4extlinux.sh.in" > \
            "${pkgdir}/usr/lib/u-boot/${_pkgname}/install-uboot4extlinux.sh" \
              -e "s|@u_boot_with_spl[@]|/usr/lib/u-boot/${_pkgname}/u-boot-sunxi-with-spl.bin|g" \
              -e "s|@u_boot_with_spl_offset[@]|${u_boot_with_spl_offset}|g"

        chmod +x \
              "${pkgdir}/usr/lib/u-boot/${_pkgname}/install-uboot4extlinux.sh"

        # Install what is required for the pacman hook
        install -d "${pkgdir}/usr/share/libalpm/hooks/"
        sed < "${srcdir}/${pkgbase}.hook.in" > \
            "${pkgdir}/usr/share/libalpm/hooks/${_pkgname}.hook" \
            -e "s|@pkgname[@]|${_pkgname}|g"

        install -d "${pkgdir}/usr/share/doc/u-boot/${_pkgname}/"
        # If we install several uboot4extlinux, we need a way to clearly
        # separate each postinstall message. To do that we wrapped the
        # text in an ASCII art square, but doing that is complicated when
        # using sed as the package name as well as the installation script
        # path both have variable length.
        sh "${srcdir}/generate-${pkgbase}-install-text.sh" \
           "${_pkgname}" \
           "${pkgbase}" \
           "/usr/lib/u-boot/${_pkgname}/install-uboot4extlinux.sh" > \
           "${pkgdir}/usr/share/doc/u-boot/${_pkgname}/install-uboot4extlinux.txt"
    fi
}

_make_pkgdesc()
{
    board_name="$1"
    echo "U-Boot with Extlinux support for ${board_name}"
}

package_uboot4extlinux-sunxi()
{
    pkgdesc="Scripts for managing U-Boot installations for computers with Allwinner System On a Chip"

    depends=('uboot-tools')

    # Users are expected to use this as a base for /boot/extlinux/extlinux.conf
    install -d "${pkgdir}/usr/lib/u-boot/${pkgname}/"
    install -Dm644 \
            "${srcdir}/extlinux.conf" \
            "${pkgdir}/usr/lib/u-boot/${pkgname}/"
}

package_uboot4extlinux-a10-olinuxino-lime()
{
    pkgdesc=$(_make_pkgdesc "A10 OLinuXino Lime")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-a10s-olinuxino-m()
{
    pkgdesc=$(_make_pkgdesc "A10s OLinuXino Micro")

    replaces=('uboot4extlinux-a10s-olinuxino-micro')

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-a13-olinuxino()
{
    pkgdesc=$(_make_pkgdesc "A13 OLinuXino")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-a13-olinuxinom()
{
    pkgdesc=$(_make_pkgdesc "uboot4extlinux-a13-olinuxino-micro")

    replaces=('uboot4extlinux-a13-olinuxino-micro')

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-a20-olinuxino-lime()
{
    pkgdesc=$(_make_pkgdesc "A20 OLinuXino Lime")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-a20-olinuxino-lime2()
{
    pkgdesc=$(_make_pkgdesc "A20 OLinuXino Lime2")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-a20-olinuxino-lime2-emmc()
{
    pkgdesc=$(_make_pkgdesc "A20 OLinuXino Lime2 with eMMC")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-a20-olinuxino_micro()
{
    pkgdesc=$(_make_pkgdesc "uboot-a20-olinuxino-micro")

    replaces=('uboot-a20-olinuxino-micro')

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-bananapi()
{
    pkgdesc=$(_make_pkgdesc "Banana Pi")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-bananapro()
{
    pkgdesc=$(_make_pkgdesc "Banana Pro")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-chip()
{
    pkgdesc=$(_make_pkgdesc "C.H.I.P")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-cubieboard()
{
    pkgdesc=$(_make_pkgdesc "Cubieboard")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-cubieboard2()
{
    pkgdesc=$(_make_pkgdesc "Cubieboard 2")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-cubietruck()
{
    pkgdesc=$(_make_pkgdesc "Cubietruck")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-linksprite_pcduino()
{
    pkgdesc=$(_make_pkgdesc "uboot4extlinux-pcduino")

    replaces=('uboot4extlinux-pcduino')

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-linksprite_pcduino3()
{
    pkgdesc=$(_make_pkgdesc "uboot4extlinux-pcduino3")

    replaces=('uboot4extlinux-pcduino3')

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-linksprite_pcduino3_nano()
{
    pkgdesc=$(_make_pkgdesc "uboot4extlinux-pcduino3-nano")

    replaces=('uboot4extlinux-pcduino3-nano')

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-orangepi_2()
{
    pkgdesc=$(_make_pkgdesc "Orange Pi 2")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-orangepi_one()
{
    pkgdesc=$(_make_pkgdesc "Orange Pi One")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-orangepi_pc()
{
    pkgdesc=$(_make_pkgdesc "Orange Pi PC")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}

package_uboot4extlinux-orangepi_plus()
{
    pkgdesc=$(_make_pkgdesc "Orange Pi Plus")

    # util-linux is needed for blkid for install-uboot4extlinux.sh
    depends=("${pkgbase}" 'util-linux')

    _make_uboot_package "${pkgname}"
}
