###############################################################################
# Helper script: /load_kernel_modules.scr/platform/aarch64/virt
# Purpose......: Set the Kernel modules for the various virtualization
#                platforms, including:
#                  Apple Silicon (UTM native Virtualization & VMWare Fusion)
#                  KVM Virtual Machine
#                  QEMU Virtual Machine
#                  Parallels Virtual Machine
#                within the Slackware initial RAM disk ('OS initrd') and the
#                Slackware Installer.
#                This script is sourced from '/load_kernel_modules'
# Author.......: Stuart Winter <mozes@slackware.com>
#              : Brenton Earl <el0226@slackware.com>
# Date.........: 23-Mar-2025
#
# Important Note:
# * You must _append_ to the module lists (as this script does)
#   otherwise the base set of modules will not be loaded and would result in
#   a Kernel panic.
# * The initrd uses the 'bash' shell, rather than 'busybox'
#   (as in upstream/x86 Slackware). This allows you (for example)
#   to use 'fallthrough' (case statements terminated with ';&'
#   rather than ';;') within case statements and regular expression
#   matches within 'if' statements.
#   This permits the 'c'-style switch statements where you can
#   'inherit' the previous matches as you move down the cases.
#   This enables you to match on varients of boards, and inherit
#   a 'baseline' of platform modules for that board.
#
# The 'PLATWALK' match is to enable build scripts to process these
# scripts outside of the initrd environment and determine which
# modules will be loaded by a particular Hardware Model.  This must remain
# in place for all scripts.
###############################################################################

# The virtualization Hardware Models typically do not provide a /proc/device-tree/model
# interface so 'dmidecode' is used.
#
# As an example, $HWM might contain the string:
# "KVM Virtual Machine virt-7.2"
# "QEMU Virtual Machine virt-7.2"
# "Parallels ARM Virtual Machine"

# NOTE: This is work in progress - the modules aren't properly categorised yet.
# Technically this makes no difference, it's just for human comprehension.

case $HWM in
   "KVM Virtual"*|"QEMU Virtual"*|"Apple Virtual"*|"VMware Apple"*|"Parallels"*|PLATWALK)
      platform_detected=1

      # Load the parent platform drivers for the SoC:
      kmod_load_subsyst_soc=1

      SOC_NAME=virtualized

      # Load the parent platform drivers for the SoC:
      kmod_load_subsyst_soc=1

      # If one of the modules within the base list is causing problems on
      # your platform, here are the options laid out as examples:
      # USB="${USB/ehci_orion/differentmodule}" # Substitute module 'ehci_orion' with 'differentmodule'
      # USB="${USB/ehci_orion/}" # Remove the 'ehci_orion' module from the list
      MOD_GPIO+="   gpio-virtio"
      # Drivers for PCI and other core sub systems:
      # virtio-vfio-pci - absent in Linux 6.12, but exists in 6.13.
      MOD_PHY+="    pci-host-generic virtio-input virtio-mmio virtio-dma-buf virtio-pci-legacy-dev virtio-pci-modern-dev virtio-pci "
      # Video/display drivers:
      MOD_VIDEO+="  bochs"
      # MFD (Multi Functional Devices) drivers:
      MOD_MFD+="    "
      # For SDHC/MMC and storage sub systems:
      MOD_CARDS+="  "
      MOD_SCSI+="   virtio-scsi virtio-blk"
      # Drivers for USB hardware for this particular Hardware Model:
      MOD_USB+="    "
      # Ethernet network driver:
      MOD_NET+="    virtio-net"
      # Any modules related to compression/decompression and cryptography
      MOD_CMP+="    "
      MOD_CRYPTO+=" virtio-crypto"

      # The following modules do not inherit from the parent loader '/load_kernel_modules'
      #MOD_RTC+="rtc_XYZ"
      # Modules for the peripherals on the Hardware Model's main board
      # (outside of the SoC itself)
      MOD_HWM+=" virtio-gpu scmi-transport-virtio i2c-virtio virtio-vdpa virtio-balloon virtio-mem virtio-iommu virtio-rng"
      # Modules for the IP blocks/peripherals embedded within the SoC:
      #MOD_SOC+=" i2c-XYZ"

      # Define a function to run from the OS InitRD's '/init' immediately prior
      # to switching into the Slackware OS proper.
      # This is after any software RAID arrays et al have been initialised.
      # There's no current use case for this, but it may be useful in the future.
      #
      # At this stage, the following paths for Slackware OS are mounted:
      # /proc, /sys, /run, /dev
      # The root file system ('/') is mounted under /mnt
      #
      #function hwm_hook_pre_switch_root() {
      #  echo "Just about to switch into the Slackware OS proper, leaving the OS InitRD"
      #  sleep 4
      #}
      ;;
esac

# Virtualization platform specific modules:
case $HWM in
   "VMware Apple"*|PLATWALK)
      # Drivers for PCI and other core sub systems:
      #MOD_PHY+="    "
      # Ethernet network driver:
      # VMWare Fusion uses the Intel e1000 driver:
      MOD_NET+=" e1000"
      ;;
esac

# Set the short name that is used by /load_kernel_modules to install
# the appropriate configuration for modprobe for this Hardware Model:
# These files are stored within the source tree:
# source/k/SlkOS-initrd-overlay/usr/share/hwm-configure/platform/aarch64/modprobe.d/
#
# Note: Typically these are only used to blacklist particular modules from loading
# within the OS InitRD or Installer.  Within the OS the regular location of
# /lib/modprobe.d/ is used and has no connection to the content of the
# OS InitRD/Installer.
# Note - lowercase $hwm is used here because it contains the name of the Hardware Model,
# where as $HWM may contain "platwalk" when the Installer is booted into generic mode.
case $hwm in
   "KVM Virtual"*|"QEMU Virtual"*|"Apple Virtual"*|"VMware Apple"*|"Parallels"*)
      HWM_SHORTNAME=virt ;;
esac

# The '/load_kernel_modules' script will load the modules
# set above.
