#!/bin/sh
set -e
# based on intel-microcode & amd64-microcode initramfs-tools hooks
# Copyright (C) 2012-2016 Henrique de Moraes Holschuh <hmh@debian.org>
# Copyright (C) 2019 Canonical Ltd
# Copyright (C) 2020 Canonical Ltd
# Released under the GPL v3
#
# Generates a copy of the minimal microcode for all Intel/AMD processors
# and installs it to the early initramfs
EFWD=$(mktemp -d "/tmp/microcode-initrd_XXXXXXXXXX")
EFWCD="${EFWD}/d/kernel/x86/microcode"
# note: to build a reproducible early initramfs, we force
# the microcode component ordering inside the microcode
# firmware file, as well as the timestamp and ordering of
# all cpio members.
mkdir -p "${EFWCD}"
find /lib/firmware/amd-ucode/ -maxdepth 1 -type f -print0 | LC_ALL=C sort -z | xargs -0 -r cat 2>/dev/null >"${EFWCD}/AuthenticAMD.bin"
iucode_tool --quiet --write-to="${EFWCD}/GenuineIntel.bin" /lib/firmware/intel-ucode/

latest_amd_mtime=$(find /lib/firmware/amd-ucode/ -type f -printf '%T@\n' | sort -n | cut -d. -f1 | tail -n1)
latest_intel_mtime=$(find /lib/firmware/intel-ucode/ -type f -printf '%T@\n' | sort -n | cut -d. -f1 | tail -n1)
touch --no-dereference --date="@${latest_amd_mtime}" "${EFWCD}/AuthenticAMD.bin"
touch --no-dereference --date="@${latest_intel_mtime}" "${EFWCD}/GenuineIntel.bin"
if [ -z "${SOURCE_DATE_EPOCH-}" ]; then
    SOURCE_DATE_EPOCH=$(printf "%s\n%s\n" "$latest_amd_mtime" "$latest_intel_mtime" | sort -n | tail -n1)
    export SOURCE_DATE_EPOCH
fi

( cd "${EFWD}/d" ; find . | LC_ALL=C sort | sed "s/$/\t\t\t\t0\t0/" | 3cpio --create "${EFWD}/microcode.cpio" )
mv "${EFWD}/microcode.cpio" /boot/
[ -d "${EFWD}" ] && rm -fr "${EFWD}"
