#!/bin/bash

#  helper script: build ROM images with depthcharge and put them in ./bin/
#
#	Copyright (C) 2014, 2015, 2016 Minifree Ltd <info@minifree.org>
#	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
