#!/bin/bash
#LAUNCH_FORK

# Note: the above token is consumed by the parent script and causes
# this script to be forked rather than sourced.
################################################################################################
# Script.....: /usr/share/hwm-configure/platform/aarch64/installer/helper.scr/000-grub-configure
# Called from: /usr/lib/setup/armedslack-postinstall-scripts/001-hwm-os-configure
# Purpose....: Configure the GRUB2 Bootloader for supported Hardware Models.
# Version....: 1.08
# Date.......: 06-Mar-2026
# Authors....: Brenton Earl <el0226@slackware.com>
#              Stuart Winter <mozes@slackware.com>
################################################################################################
#
# TODO:
# * Error handling/surfacing of errors.
# * Ability to configure Kernel cmdline? We don't for U-Boot.
################################################################################################
# Changelog
# v1.08, 06-Mar-2026
# Added modprobe.blacklist=msm,qcom_q6v5_pas to Lenovo ThinkPad x13s Kernel command line.
# v1.07, 12-Apr-2025
# Added support for Virtualization platforms on macOS.
# Added support for installing GRUB onto unknown Hardware Models.
# v1.06, 13-May-2024
# Added support for Lenovo ThinkPad x13s
################################################################################################

# Copyright 2023-2026 Brenton Earl, Utah, USA.
# Copyright 2024-2025 Stuart Winter, Donostia, Spain.
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Only install and configure GRUB if the Kernel cmdline operator 'bl_grub' is present.
# This enables us to easily determine whether we're meant to configure GRUB on this Hardware Model
# rather than perform a number of tests on the presence of files, etc.
# We exit silently without error if the cmdline token isn't present, since this doesn't constitute
# an error.
cmdline_has bl_grub || exit 0

# Determine the Hardware Model name:
export HWM=$( slk-hwm-discover )
# Determine archtecture:
ARCH=$( slk-hwm-discover --print-arch )

# Location of the root file system:
T_PX=$1
# Installer's temporary location:
TMP=${TMP:-/var/log/setup/tmp}

# The GRUB Boot Loader configuration template:
GRUB_TEMPLATE=/usr/share/hwm-configure/platform/${ARCH}/installer/assets/bootloader/grub/template-grub.cfg
[ ! -s ${GRUB_TEMPLATE} ] && exit 1

# GRUB requires an EFI partition. /usr/lib/setup/SeTEFI labels our EFI partition.
# If we don't find it labeled, we can exit silently.
[ -z "$( lsblk -o label -Mrin | grep -E 'SLKefi$' )" ] && exit 0

# Ensure that the GRUB installer is present:
[ ! -x $T_PX/usr/sbin/grub-install ] && exit 1

# Global settings applicable to all Hardware Models:
#
# Determine the root file system type set for this installation.
# This is stored earlier in the installation process by
# /usr/lib/setup/armedslack-SeTpartitions
[ -s ${TMP}/root_sys_type ] && conf_root_fstype="$( < ${TMP}/root_sys_type )"

# Root device's file system label:
# Note: future possibility: need to handle statically set '--label SLKroot' within
# the grub template config file. Not worth the effort unless people start going crazy
# customising stuff.
[ -s ${TMP}/SeTrootdev_labeled ] && conf_root_dev="$( < ${TMP}/SeTrootdev_labeled )"

# Location of the Grub configuration file
# This is contained within the Operating System's /boot directory.
ARMEDSLACK_GRUBCONF=${T_PX}/boot/grub/grub.cfg

# Set boot parameters for supported Hardware Models:
# This may be split into helper scripts (a la Kernel Module Loader)
# if the number of boards exceeds several.
case $HWM in
   "SolidRun CEX7 Platform"*|"SolidRun LX2160A Honeycomb"*)
      hwm_grub_supported=1
      # Virtual Console setting:
      conf_console=tty1
      # Device Tree Blob:
      # -- actually is used, but we may not in the future since lspci doesn't work
      #    and the fan sits on full speed. Without DT both work, but MMC doesn't!
      #    Not currently used but we'll leave it in for the time being:
      conf_dt="devicetree /boot/dtb/freescale/fsl-lx2160a-honeycomb.dtb"
      # Don't append "platwalk" to the Kernel cmdline, if we're called in generic
      # mode (e.g. using the generic AArch64 EFI bootable Installer ISO).
      no_append_platwalk=1
      # Kernel Command Line settings:
      # TODO: Look up to see if thre is a patch for these so they can be removed
      # These boot args were recommended in the Solid Run developer center
      # https://solidrun.atlassian.net/wiki/spaces/developer/overview
      conf_kernel_cmdline="arm-smmu.disable_bypass=0 amdgpu.pcie_gen_cap=0x4 amdgpu.noretry=0" ;;

    "Lenovo ThinkPad X13s"*)
      hwm_grub_supported=1
      # Virtual Console setting:
      conf_console=tty1
      # Device Tree Blob:
      conf_dt="devicetree /boot/dtb/qcom/sc8280xp-lenovo-thinkpad-x13s.dtb"
      # Don't append "platwalk" to the Kernel cmdline, if we're called in generic
      # mode (e.g. using the generic AArch64 EFI bootable Installer ISO).
      no_append_platwalk=1
      # Kernel Command Line settings:
      # TODO: Look up to see if there is a patch for these so they can be removed
      # https://wiki.gentoo.org/wiki/Lenovo_ThinkPad_X13s
      # https://fedoraproject.org/wiki/Thinkpad_X13s
      # https://wiki.debian.org/InstallingDebianOn/Thinkpad/X13s
      # Fedora recommends blacklisting the msm and/or qcom_q6v5_pas kernel modules for
      # fresh installations, while the installer is running.  Debian has similar recommendations
      # on the debian wiki.
      conf_kernel_cmdline="arm64.nopauth clk_ignore_unused pd_ignore_unused modprobe.blacklist=msm,qcom_q6v5_pas" ;;

     "KVM Virtual"*|"QEMU Virtual"*|"Apple Virtual"*|"VMware Apple"*|"Parallels"*)
      hwm_grub_supported=1
      # Virtual Console setting:
      #conf_console=hvc0
      unset conf_console # unneeded on the VM platforms
      # Device Tree Blob - null unneeded on Virtualization platforms:
      conf_dt=""
      # Don't append "platwalk" to the Kernel cmdline, if we're called in generic
      # mode (e.g. using the generic AArch64 EFI bootable Installer ISO).
      # The virtualized platforms are installed in generic mode, but we also
      # support them directly (we know which modules to load), so we can
      # use the standard module loading process.
      no_append_platwalk=1
      # Strip the headless (serial) boot menu option:
      strip_headless=1
      # Strip the UEFI firmware configuration boot menu option:
      #strip_uefifw=1
      # Kernel Command Line settings.
      # None for Apple Virtualization:
      conf_kernel_cmdline="" ;;

      # Unsupported/Unknown Hardware Models.
      # We'll set some generic settings and let the user decide if they want to
      # install GRUB.
      *)
      unset hwm_grub_supported
      # Virtual Console setting:
      #conf_console=tty1
      # Who knows what this should be - leave empty and let the user discover
      unset conf_console
      # Strip the headless (serial) boot menu option
      # This will invariably be wrong since the serial port is different across
      # Hardware Models
      strip_headless=1
      # Device Tree Blob:
      conf_dt=""
      # Kernel Command Line setting:
      conf_kernel_cmdline="" ;;
esac

# If the Hardware Model is unknown/unsupported, but we have an EFI partition
# set up, we'll offer the user the optionm to install GRUB and suggest they review
# the settings prior to rebooting into the OS.
if [ -z "${hwm_grub_supported}" ]; then
   dialog \
      --backtitle "Bootware" \
      --colors \
      --title "INSTALL BOOT LOADER ON UNKNOWN HARDWARE MODEL" \
      --yes-label "INSTALL" \
      --no-label "SKIP" \
      --yesno \
"\n
Hardware Model: \Zb\Zr\Z1 ${HWM} \Z1\Zn\n\n
This Hardware Model is not directly supported by Slackware, so the boot loader cannot be automatically configured.\n\n
However, a boot loader must be installed to boot the OS. Since this system is EFI-capable, GRUB can be installed.\n\n
A generic GRUB configuration can be installed now, and you can review and edit the configuration later by opening a shell at the
end of the Slackware installation process.\n
\n
The GRUB configuration file is \Zb\Z7${ARMEDSLACK_GRUBCONF} \Zn\n\n
For any changes to take effect, simply save the file, and reboot.\n\n
\nIt is recommended to install the boot loader.\n" 0 0
[ $? -eq 1 ] && exit 0 # quit if the user picked 'SKIP'
fi

# If the Kernel cmdline option "platwalk" is specified in the
# Slackware Installer GRUB config (as it is for the 'generic'
# ISO), carry this through to the OS:
# Some Hardware Models may be booted with the generic ISO, but are
# supported officially. In such cases we don't want to have the Kernel module
# loader (within the OS InitRD) to run in "generic" mode, since we know
# which modules are required.
{ grep -qw "platwalk" /proc/cmdline && [ -z "$no_append_platwalk" ] ;} && conf_kernel_cmdline+=" platwalk"

# Install AArch64 version of grub into /boot/grub
# Install AArch64 UEFI firmware shipped with grub into /boot/efi
mkdir -pm755 ${T_PX}/boot/grub
dialog \
   --backtitle "Bootware" \
   --sleep 3 \
   --infobox "Configuring Boot Loader..." 3 30
grub-install \
   -d $T_PX/usr/lib64/grub/arm64-efi \
   --force \
   --removable \
   --no-floppy \
   --target=arm64-efi \
   --boot-directory=${T_PX}/boot \
   --efi-directory=${T_PX}/boot/efi || exit 1

# Install the generic GRUB configuration template:
install -pm644 ${GRUB_TEMPLATE} ${ARMEDSLACK_GRUBCONF} || exit 1

#
# Configure the template with this Hardware Model's settings:
#
# Configure the console:
if [ -z "${conf_console}" ]; then
   sed -i 's?console=%CONSOLE%??g' ${ARMEDSLACK_GRUBCONF}
 else
   sed -i 's?%CONSOLE%?'"${conf_console}"'?' ${ARMEDSLACK_GRUBCONF}
fi
# Root file system type:
sed -i 's?%ROOTFSTYPE%?'"${conf_root_fstype}"'?' ${ARMEDSLACK_GRUBCONF}
# Root file system location:
sed -i 's?%ROOTDEV%?'"${conf_root_dev}"'?' ${ARMEDSLACK_GRUBCONF}
# Kernel cmdline settings:
sed -i 's?%POST_INST_OS_CMDLINE_APPEND%?'"${conf_kernel_cmdline}"'?' ${ARMEDSLACK_GRUBCONF}

# Configure Device Tree:
if [ ! -z "${conf_dt}" ]; then
   sed -i 's?%DEVICETREE%?'"${conf_dt}"'?' ${ARMEDSLACK_GRUBCONF}
 else
   # No Device Tree configured, remove the setting:
   sed -i '/%DEVICETREE%/d' ${ARMEDSLACK_GRUBCONF}
fi

# Strip the headless (serial) boot menu option?
[ ! -z "${strip_headless}" ] && sed -i '/^##SLKOSheadless/,/^##SLKOSheadless/d' ${ARMEDSLACK_GRUBCONF}
# Strip the UEFI firmware settings configuration boot menu option?
[ ! -z "${strip_uefifw}" ] && sed -i '/^##SLKuefi_settings/,/^##SLKuefi_settings/d' ${ARMEDSLACK_GRUBCONF}

# Wait a couple of seconds to avoid this flashing off the
# screen too raipdly (often giving the impression of an error):
sleep 3
