#!/bin/bash

#  helper script: build ROM images with depthcharge and put them in ./bin/
#
#	Copyright (C) 2014, 2015, 2016 Francis Rowe <info@gluglug.org.uk>
#	Copyright (C) 2015 Paul Kocialkowski <contact@paulk.fr>
#
#    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 3 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/>.
#

# This script assumes that the working directory is the
# root of libreboot_src or libreboot git.

[ "x${DEBUG+set}" = 'xset' ] && set -v
set -u -e
if [ -z ${NPROC+x} ]; then
    cores="$(nproc)"
else
    case ${NPROC} in
        ''|*[!0-9]*)
            printf "value '%s' for NPROC is invalid. non-numeric. Exiting.\n" "${NPROC}"
            exit 1
            ;;
    esac
    cores="${NPROC}"
fi

printf "Building ROM images with the depthcharge payload\n"

if [ ! -d "bin/" ]
then
	mkdir "bin/"
fi

if [ -f "version" ]; then
	# _src release archive is being used
	version="$(cat "version")"
else
	# git repo is being used
	version="$(git describe --tags HEAD)" # note: in libreboot, coreboot/.git doesn't exist, this uses libreboot .git
fi

# Build libpayload
# ------------------------------------------------------------------------------

buildlibpayload() {
	family="${1}"
	board="${2}"
    cbrevision="${3}"
    vbootrevision="${4}"

	( 
    cd "coreboot/${cbrevision}/${cbrevision}/"
    git checkout depthcharge_${board}
    (
        cd "3rdparty/vboot/"
        git checkout depthcharge_${board}
    )

    cd "payloads/libpayload/"

	make distclean
	rm -Rf "install/"

	make KBUILD_DEFCONFIG="configs/config.$family" defconfig
	make -j${cores}
	make DESTDIR="install" install

    cd "../../"
    git checkout master
    cd "3rdparty/vboot/"
    git checkout master
	)
}

# Build depthcharge
# ------------------------------------------------------------------------------

builddepthcharge() {
	board="${1}"
    cbrevision="${2}"
    vbootrevision="${3}"

	(
    (
        cd "coreboot/${cbrevision}/${cbrevision}/"
        git checkout depthcharge_${board}
        cd "3rdparty/vboot/"
        git checkout depthcharge_${board}
    )
    cd "depthcharge/"

	make distclean
	rm -f "../coreboot/${cbrevision:?}/${cbrevision:?}/depthcharge.elf"

	make BOARD="${board}" defconfig
	make BOARD="${board}" LIBPAYLOAD_DIR="$(pwd)/../coreboot/${cbrevision}/${cbrevision}/payloads/libpayload/install/libpayload" VB_SOURCE="$(pwd)/../coreboot/${cbrevision}/${cbrevision}/3rdparty/vboot" -j${cores} depthcharge_unified

	cp "build/depthcharge.elf" "../coreboot/${cbrevision}/${cbrevision}/"

    cd "../coreboot/${cbrevision}/${cbrevision}/"
    git checkout master
    cd "3rdparty/vboot/"
    git checkout master
	)
}

# Build coreboot
# ------------------------------------------------------------------------------

buildcoreboot() {
	board="${1}"
    cbrevision="${2}"
    vbootrevision="${3}"

	(
	cd "coreboot/${cbrevision}/${cbrevision}"
    git checkout depthcharge_${board}
    (
        cd "3rdparty/vboot/"
        git checkout depthcharge_${board}
    )

	make distclean
	rm -f ".coreboot-version"
	rm -f *.img

	printf 'libreboot-%s' "${version}" > "ro-frid"
	printf 'libreboot-%s\n' "${version}" > ".coreboot-version" # needed for reproducible builds in coreboot

	make KBUILD_DEFCONFIG="$(pwd)/../../../resources/libreboot/config/depthcharge/${board}/config" defconfig
	make -j${cores}

	cbfs_size=$( grep CONFIG_CBFS_SIZE ".config" | sed "s/.*[[:space:]]*=[[:space:]]*//g" )
	cbfs_size=$( printf "%d\n" "${cbfs_size}" )
	cbfs_size=$(( $cbfs_size / 1024 ))

	dd if="build/coreboot.rom" of="coreboot.img" bs=1024 count="${cbfs_size}"

	objcopy -I binary -O binary --pad-to=0x100 --gap-fill=0x00 "ro-frid" "ro-frid.img"

	# prepare directory for new images
	rm -Rf "${board:?}/"
	mkdir "${board}/"
	# move the images into the newly created directory
	mv "coreboot.img" "${board}/"
	mv "ro-frid.img" "${board}/"
	# copy the scripts too
	cp "../../../resources/libreboot/install/depthcharge/cros-flash-replace" "${board}/"
	cp "../../../resources/libreboot/install/depthcharge/${board}/layout.txt" "${board}/"
	# delete the old images from ../bin
	rm -Rf "../../../bin/depthcharge/${board}/"
	# now put the new images in ./bin/depthcharge/
	[ ! -d "../../../bin/depthcharge/" ] && mkdir -p "../../../bin/depthcharge/"
	mv "${board}/" "../../../bin/depthcharge/"

	# clean this up
	rm -f "depthcharge.elf"
	rm -f *.img

    git checkout master
    cd "3rdparty/vboot/"
    git checkout master
	)
}

# Build ROM images for supported boards
buildrom() {
	board="${1}"
    cbrevision="$(cat resources/libreboot/config/depthcharge/${board}/cbrevision)"
    vbootrevision="$(cat resources/libreboot/config/depthcharge/${board}/vbootrevision)"

	if [ -f "resources/libreboot/config/depthcharge/${board}/config" ]; then
		family=$( echo ${board} |sed "s/_.*//g" )

		buildlibpayload "${family}" "${board}" "${cbrevision}" "${vbootrevision}"
		builddepthcharge "${board}" "${cbrevision}" "${vbootrevision}" 
		buildcoreboot "${board}" "${cbrevision}" "${vbootrevision}"
	fi
}

if [ $# -gt 0 ]; then
	for board in "${@}"; do
		buildrom "${board}"
	done
else
	for board in resources/libreboot/config/depthcharge/*; do
		buildrom "${board##*/}"
	done
fi