diff --git a/bin/omarchy-hw-qualcomm-soc b/bin/omarchy-hw-qualcomm-soc new file mode 100755 index 00000000000..c85c73b1e5e --- /dev/null +++ b/bin/omarchy-hw-qualcomm-soc @@ -0,0 +1,5 @@ +#!/bin/bash + +# omarchy:summary=Detect a Qualcomm SoC from the boot device tree. + +tr '\0' '\n' /dev/null | grep -q '^qcom,' diff --git a/default/pacman/mirrorlist-aarch64 b/default/pacman/mirrorlist-aarch64 new file mode 100644 index 00000000000..c7185ed8f65 --- /dev/null +++ b/default/pacman/mirrorlist-aarch64 @@ -0,0 +1,2 @@ +# Arch Linux ARM publishes this endpoint with a $arch/$repo layout. +Server = http://mirror.archlinuxarm.org/$arch/$repo diff --git a/default/pacman/pacman-aarch64.conf b/default/pacman/pacman-aarch64.conf new file mode 100644 index 00000000000..b11e10a47c7 --- /dev/null +++ b/default/pacman/pacman-aarch64.conf @@ -0,0 +1,30 @@ +# See the pacman.conf(5) manpage for option and repository directives +# Arch Linux ARM provides the aarch64 repositories used below. + +[options] +Color +ILoveCandy +VerbosePkgLists +HoldPkg = pacman glibc +Architecture = auto +CheckSpace +ParallelDownloads = 5 +DownloadUser = alpm + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional + +# pacman searches repositories in the order defined here. +[core] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +[alarm] +Include = /etc/pacman.d/mirrorlist + +[aur] +Include = /etc/pacman.d/mirrorlist diff --git a/etc/mkinitcpio.conf.d/thunderbolt_module.conf b/etc/mkinitcpio.conf.d/thunderbolt_module.conf index 9518f8b1201..eb0565bef59 100644 --- a/etc/mkinitcpio.conf.d/thunderbolt_module.conf +++ b/etc/mkinitcpio.conf.d/thunderbolt_module.conf @@ -1 +1,4 @@ -MODULES+=(thunderbolt) +# linux-aarch64 does not provide the thunderbolt module. +if [[ $(uname -m) == x86_64 ]]; then + MODULES+=(thunderbolt) +fi diff --git a/install/hardware/all.sh b/install/hardware/all.sh index 9b54d1c0192..7e47477fa74 100644 --- a/install/hardware/all.sh +++ b/install/hardware/all.sh @@ -41,7 +41,12 @@ run_logged "$OMARCHY_INSTALL/hardware/apple/fix-suspend-nvme.sh" run_logged "$OMARCHY_INSTALL/hardware/apple/fix-t2.sh" run_logged "$OMARCHY_INSTALL/hardware/apple/fix-brcmfmac-supplicant.sh" +run_logged "$OMARCHY_INSTALL/hardware/qualcomm/dtb-uki.sh" +run_logged "$OMARCHY_INSTALL/hardware/qualcomm/kernel-params.sh" +run_logged "$OMARCHY_INSTALL/hardware/qualcomm/firmware.sh" + run_logged "$OMARCHY_INSTALL/hardware/lenovo/fix-yoga-pro7-bass-speakers.sh" +run_logged "$OMARCHY_INSTALL/hardware/lenovo/yoga-slim7x.sh" run_logged "$OMARCHY_INSTALL/hardware/fix-bcm43xx.sh" run_logged "$OMARCHY_INSTALL/hardware/fix-surface-keyboard.sh" diff --git a/install/hardware/lenovo/start-yoga-slim7x-remoteprocs.sh b/install/hardware/lenovo/start-yoga-slim7x-remoteprocs.sh new file mode 100644 index 00000000000..ec7a5c94197 --- /dev/null +++ b/install/hardware/lenovo/start-yoga-slim7x-remoteprocs.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +set -euo pipefail + +remoteproc_root=${OMARCHY_YOGA_REMOTEPROC_ROOT:-/sys/class/remoteproc} +attempts=${OMARCHY_YOGA_REMOTEPROC_ATTEMPTS:-30} +sleep_seconds=${OMARCHY_YOGA_REMOTEPROC_SLEEP:-1} + +for ((attempt = 1; attempt <= attempts; attempt++)); do + adsp_started=0 + shopt -s nullglob + + for state_file in "$remoteproc_root"/remoteproc*/state; do + remoteproc=${state_file%/state} + [[ -r $remoteproc/firmware && -r $state_file ]] || continue + + firmware=$(tr -d '\0\n' <"$remoteproc/firmware") + case "$firmware" in + *qcadsp*) kind=ADSP ;; + *qccdsp*) kind=CDSP ;; + *) continue ;; + esac + + if [[ $(<$state_file) == running ]]; then + echo "Yoga Slim 7x: $kind is already running" + [[ $kind == ADSP ]] && adsp_started=1 + elif [[ -w $state_file ]] && printf 'start\n' >"$state_file"; then + echo "Yoga Slim 7x: started $kind" + [[ $kind == ADSP ]] && adsp_started=1 + else + echo "Yoga Slim 7x: could not start $kind ($firmware)" >&2 + fi + done + + ((adsp_started)) && exit 0 + sleep "$sleep_seconds" +done + +echo "Yoga Slim 7x: audio DSP did not appear or could not be started" >&2 +exit 1 diff --git a/install/hardware/lenovo/yoga-slim7x.sh b/install/hardware/lenovo/yoga-slim7x.sh new file mode 100644 index 00000000000..dede8968540 --- /dev/null +++ b/install/hardware/lenovo/yoga-slim7x.sh @@ -0,0 +1,58 @@ +# Lenovo Yoga Slim 7x (14Q8X9 / 83ED) board-specific setup. + +yoga_slim7x_compatible="" +compatible_path=${OMARCHY_YOGA_COMPATIBLE_PATH:-/sys/firmware/devicetree/base/compatible} +modules_load_dir=${OMARCHY_YOGA_MODULES_LOAD_DIR:-/etc/modules-load.d} +mkinitcpio_dir=${OMARCHY_YOGA_MKINITCPIO_DIR:-/etc/mkinitcpio.conf.d} +limine_config_dir=${OMARCHY_YOGA_LIMINE_CONFIG_DIR:-/etc/limine-entry-tool.d} +systemd_dir=${OMARCHY_YOGA_SYSTEMD_DIR:-/etc/systemd/system} + +if [[ -r $compatible_path ]]; then + yoga_slim7x_compatible=$(tr '\0' '\n' <"$compatible_path") +fi + +if omarchy-hw-qualcomm-soc && + { grep -qi '^lenovo,yoga-slim7x$' <<<"$yoga_slim7x_compatible" || + omarchy-hw-match 'Yoga Slim 7x' || omarchy-hw-match '83ED'; }; then + echo "Detected Lenovo Yoga Slim 7x, applying board-specific support..." + + # The Yoga exposes its CPU performance domains through SCMI. + mkdir -p "$modules_load_dir" + echo "scmi-cpufreq" >"$modules_load_dir/yoga-slim7x.conf" + + # Initialize the internal keyboard and display before disk unlock. + mkdir -p "$mkinitcpio_dir" + cat >"$mkinitcpio_dir/yoga-slim7x-initramfs.conf" <<'CONF' +MODULES+=(i2c-hid-of qrtr ps883x pmic_glink_altmode) + +for firmware in \ + /usr/lib/firmware/qcom/gen70500_sqe.fw \ + /usr/lib/firmware/qcom/gen70500_gmu.bin \ + /usr/lib/firmware/qcom/x1e80100/LENOVO/83ED/qcdxkmsuc8380.mbn; do + [[ -f $firmware ]] && FILES+=("$firmware") +done +unset firmware +CONF + + mkdir -p "$limine_config_dir" + cat >"$limine_config_dir/yoga-slim7x.conf" <<'CONF' +KERNEL_CMDLINE[default]+=" initcall_blacklist=simpledrm_platform_driver_init" +CONF + + # Start the board's DSP remote processors. + mkdir -p "$systemd_dir" + cat >"$systemd_dir/yoga-slim7x-remoteprocs.service" <<'UNIT' +[Unit] +Description=Start the Lenovo Yoga Slim 7x DSPs +ConditionPathExists=!/etc/modprobe.d/qualcomm-adsp-nofw.conf + +[Service] +Type=oneshot +ExecStart=/bin/bash /usr/share/omarchy/install/hardware/lenovo/start-yoga-slim7x-remoteprocs.sh +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target +UNIT + systemctl enable yoga-slim7x-remoteprocs.service +fi diff --git a/install/hardware/qualcomm/dtb-uki.sh b/install/hardware/qualcomm/dtb-uki.sh new file mode 100644 index 00000000000..07bd8eb2005 --- /dev/null +++ b/install/hardware/qualcomm/dtb-uki.sh @@ -0,0 +1,51 @@ +# Embed Qualcomm device trees so systemd-stub can select one from SMBIOS data. +# DeviceTreeAuto requires literal paths, so hardware setup refreshes the list. + +if omarchy-hw-qualcomm-soc; then + omarchy-pkg-add systemd-ukify + + dtb_dir=${OMARCHY_QUALCOMM_DTB_DIR:-/boot/dtbs/qcom} + uki_config=${OMARCHY_QUALCOMM_UKI_CONFIG:-/etc/kernel/uki.conf} + dtbs=() + for dtb in "$dtb_dir"/x1*.dtb "$dtb_dir"/hamoa*.dtb \ + "$dtb_dir"/glymur*.dtb "$dtb_dir"/sc8280xp*.dtb; do + if [[ -f $dtb && $dtb != *-el2.dtb ]]; then + dtbs+=("$dtb") + fi + done + + if ((${#dtbs[@]} == 0)); then + echo "No Windows-on-ARM device trees under $dtb_dir; the UKI gets no .dtbauto sections" >&2 + else + managed_begin="# BEGIN OMARCHY QUALCOMM DEVICE TREES" + managed_end="# END OMARCHY QUALCOMM DEVICE TREES" + + mkdir -p "$(dirname "$uki_config")" + uki_tmp=$(mktemp "${uki_config}.XXXXXX") + + if [[ -f $uki_config ]]; then + cp -p "$uki_config" "$uki_tmp" + awk -v begin="$managed_begin" -v end="$managed_end" ' + $0 == begin { managed = 1; next } + managed && $0 == end { managed = 0; next } + !managed { print } + ' "$uki_config" >"$uki_tmp" + else + chmod 0644 "$uki_tmp" + fi + + { + echo + echo "$managed_begin" + echo "# Generated by Omarchy for Qualcomm Snapdragon devices." + echo "# systemd-stub selects a device tree from SMBIOS data." + echo "# Rerun 'omarchy apply hardware' after a kernel update adds new boards." + echo "[UKI]" + echo "DeviceTreeAuto=${dtbs[*]}" + echo "$managed_end" + } >>"$uki_tmp" + + mv -f "$uki_tmp" "$uki_config" + echo "Listed ${#dtbs[@]} device trees in $uki_config" + fi +fi diff --git a/install/hardware/qualcomm/firmware.sh b/install/hardware/qualcomm/firmware.sh new file mode 100644 index 00000000000..a25a0a5792d --- /dev/null +++ b/install/hardware/qualcomm/firmware.sh @@ -0,0 +1,29 @@ +# Install packaged Qualcomm firmware and vendor-signed blobs extracted from Windows. +# Keep the DSP driver disabled when starting it could disconnect the root disk. + +if omarchy-hw-qualcomm-soc; then + omarchy-pkg-add linux-firmware-qcom qcom-firmware-extract + + qcom-firmware-extract --install --no-rebuild + + modprobe_dir=${OMARCHY_QUALCOMM_MODPROBE_DIR:-/etc/modprobe.d} + root_source=$(findmnt -no SOURCE --nofsroot / 2>/dev/null || true) + + mkdir -p "$modprobe_dir" + if [[ -n $root_source ]] && lsblk -sno TRAN "$root_source" 2>/dev/null | grep -q '^usb$'; then + # Starting the DSPs resets USB-C, so keep them off when root is on USB. + cat >"$modprobe_dir/qualcomm-adsp-nofw.conf" <<'CONF' +# Generated by Omarchy for Qualcomm Snapdragon devices. +# Keep the DSP driver off while the root disk is attached over USB. +blacklist qcom_q6v5_pas +CONF + elif qcom-firmware-extract --list-missing | grep -q 'adsp'; then + cat >"$modprobe_dir/qualcomm-adsp-nofw.conf" <<'CONF' +# Generated by Omarchy for Qualcomm Snapdragon devices. +# Keep the DSP driver off until its signed firmware is installed. +blacklist qcom_q6v5_pas +CONF + else + rm -f "$modprobe_dir/qualcomm-adsp-nofw.conf" + fi +fi diff --git a/install/hardware/qualcomm/kernel-params.sh b/install/hardware/qualcomm/kernel-params.sh new file mode 100644 index 00000000000..4536395f557 --- /dev/null +++ b/install/hardware/qualcomm/kernel-params.sh @@ -0,0 +1,13 @@ +# Add firmware workarounds required by current Snapdragon laptops. + +DROP_IN="/etc/limine-entry-tool.d/qualcomm-snapdragon.conf" + +if omarchy-hw-qualcomm-soc; then + mkdir -p /etc/limine-entry-tool.d + cat >"$DROP_IN" <<'CONF' +# Generated by Omarchy for Qualcomm Snapdragon devices. +# Keep display and I/O resources enabled until their drivers load. +# Disable pointer authentication and waiting for an unavailable TPM. +KERNEL_CMDLINE[default]+=" clk_ignore_unused pd_ignore_unused arm64.nopauth systemd.tpm2_wait=0" +CONF +fi diff --git a/install/hardware/vulkan.sh b/install/hardware/vulkan.sh index a2447d46ffa..e13de205b8c 100644 --- a/install/hardware/vulkan.sh +++ b/install/hardware/vulkan.sh @@ -15,6 +15,11 @@ for vendor in "${!VULKAN_DRIVERS[@]}"; do fi done +# Adreno GPUs are platform devices, so lspci never sees them. +if omarchy-hw-qualcomm-soc; then + PACKAGES+=(vulkan-freedreno) +fi + if (( ${#PACKAGES[@]} > 0 )); then omarchy-pkg-add "${PACKAGES[@]}" fi diff --git a/install/omarchy-other.packages b/install/omarchy-other.packages index e5d56d566fe..1a7be9fec7b 100644 --- a/install/omarchy-other.packages +++ b/install/omarchy-other.packages @@ -75,3 +75,6 @@ t2fanrd # Framework 16 qmk-hid + +# Qualcomm Snapdragon support packages +qcom-firmware-extract diff --git a/install/post-install/pacman.sh b/install/post-install/pacman.sh index 23580b3c527..be3549d7c33 100644 --- a/install/post-install/pacman.sh +++ b/install/post-install/pacman.sh @@ -1,7 +1,18 @@ -# Configure pacman after package installation completes. Offline target package -# installs use the live ISO's offline pacman.conf until this final restore. -cp -f "$OMARCHY_PATH/default/pacman/pacman-${OMARCHY_MIRROR:-stable}.conf" /etc/pacman.conf -cp -f "$OMARCHY_PATH/default/pacman/mirrorlist-${OMARCHY_MIRROR:-stable}" /etc/pacman.d/mirrorlist +# Replace the installer's offline pacman configuration with online repositories. +if [[ $(uname -m) == aarch64 ]]; then + # Install the keyring before replacing the offline package source. + omarchy-pkg-add archlinuxarm-keyring + + cp -f "$OMARCHY_PATH/default/pacman/pacman-aarch64.conf" /etc/pacman.conf + cp -f "$OMARCHY_PATH/default/pacman/mirrorlist-aarch64" /etc/pacman.d/mirrorlist + + # Trust every installed keyring before the first signed sync. + pacman-key --init + pacman-key --populate +else + cp -f "$OMARCHY_PATH/default/pacman/pacman-${OMARCHY_MIRROR:-stable}.conf" /etc/pacman.conf + cp -f "$OMARCHY_PATH/default/pacman/mirrorlist-${OMARCHY_MIRROR:-stable}" /etc/pacman.d/mirrorlist +fi # omarchy-settings skips this override until cups-browsed is actually present # to avoid pacman creating cups-browsed.conf.pacnew during ISO package install. diff --git a/install/user/mise-work.sh b/install/user/mise-work.sh index f77d5561e0e..17ea1e25df9 100644 --- a/install/user/mise-work.sh +++ b/install/user/mise-work.sh @@ -19,7 +19,12 @@ case ${OMARCHY_SETUP_CONTEXT:-runtime} in esac if [[ -n $NODE_PACKAGE_DIR ]]; then - NODE_TARBALL=$(find "$NODE_PACKAGE_DIR" -name "node-v*-linux-x64.tar.gz" -type f 2>/dev/null | head -n1) + # Node names its builds x64/arm64, not by uname + case "$(uname -m)" in + aarch64) _NODE_ARCH=arm64 ;; + *) _NODE_ARCH=x64 ;; + esac + NODE_TARBALL=$(find "$NODE_PACKAGE_DIR" -name "node-v*-linux-${_NODE_ARCH}.tar.gz" -type f 2>/dev/null | head -n1) if [[ -z $NODE_TARBALL ]]; then if [[ ${OMARCHY_SETUP_CONTEXT:-} == "provision-owner" ]]; then # A factory snapshot predating the bundled tarball may not have it staged. @@ -31,7 +36,7 @@ if [[ -n $NODE_PACKAGE_DIR ]]; then exit 1 fi else - NODE_VERSION=$(basename "$NODE_TARBALL" | sed 's/node-v\(.*\)-linux-x64.tar.gz/\1/') + NODE_VERSION=$(basename "$NODE_TARBALL" | sed "s/node-v\\(.*\\)-linux-${_NODE_ARCH}.tar.gz/\\1/") NODE_INSTALL_DIR="$HOME/.local/share/mise/installs/node/$NODE_VERSION" mkdir -p "$NODE_INSTALL_DIR" diff --git a/test/shell.d/snapdragon-hardware-test.sh b/test/shell.d/snapdragon-hardware-test.sh new file mode 100644 index 00000000000..f227825fd26 --- /dev/null +++ b/test/shell.d/snapdragon-hardware-test.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +set -euo pipefail + +source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" + +firmware_setup="$ROOT/install/hardware/qualcomm/firmware.sh" +dtb_setup="$ROOT/install/hardware/qualcomm/dtb-uki.sh" +scratch=$(mktemp -d) +trap 'rm -rf "$scratch"' EXIT + +bash -n "$firmware_setup" "$dtb_setup" || fail "Snapdragon hardware scripts have valid syntax" + +( + omarchy-hw-qualcomm-soc() { return 0; } + omarchy-pkg-add() { :; } + qcom-firmware-extract() { :; } + findmnt() { + [[ $* == "-no SOURCE --nofsroot /" ]] || fail "Snapdragon firmware setup strips the Btrfs subvolume suffix" + printf '/dev/mapper/root\n' + } + lsblk() { + [[ ${!#} == "/dev/mapper/root" ]] || fail "Snapdragon firmware setup passes a resolvable root device to lsblk" + printf 'usb\n' + } + + OMARCHY_QUALCOMM_MODPROBE_DIR="$scratch/modprobe.d" + source "$firmware_setup" +) + +[[ -f $scratch/modprobe.d/qualcomm-adsp-nofw.conf ]] || + fail "Snapdragon firmware setup protects a USB-backed root disk" + +mkdir -p "$scratch/dtbs" +: >"$scratch/dtbs/x1e80100-test.dtb" +: >"$scratch/dtbs/x1e80100-test-el2.dtb" +cat >"$scratch/uki.conf" <<'CONF' +[UKI] +SecureBootPrivateKey=/secure/db.key +PCRPrivateKey=/secure/pcr.key +CONF + +run_dtb_setup() ( + omarchy-hw-qualcomm-soc() { return 0; } + omarchy-pkg-add() { :; } + + OMARCHY_QUALCOMM_DTB_DIR="$scratch/dtbs" + OMARCHY_QUALCOMM_UKI_CONFIG="$scratch/uki.conf" + source "$dtb_setup" +) + +run_dtb_setup +run_dtb_setup + +grep -Fq 'SecureBootPrivateKey=/secure/db.key' "$scratch/uki.conf" || + fail "Snapdragon DTB setup preserves Secure Boot settings" +grep -Fq 'PCRPrivateKey=/secure/pcr.key' "$scratch/uki.conf" || + fail "Snapdragon DTB setup preserves PCR settings" +[[ $(grep -Fc '# BEGIN OMARCHY QUALCOMM DEVICE TREES' "$scratch/uki.conf") == 1 ]] || + fail "Snapdragon DTB setup keeps one managed UKI block" +grep -Fq "DeviceTreeAuto=$scratch/dtbs/x1e80100-test.dtb" "$scratch/uki.conf" || + fail "Snapdragon DTB setup lists the matching device tree" +if grep -Fq 'x1e80100-test-el2.dtb' "$scratch/uki.conf"; then + fail "Snapdragon DTB setup excludes EL2-only device trees" +fi + +pass "Snapdragon setup preserves UKI settings and detects USB root disks" diff --git a/test/shell.d/yoga-slim7x-hardware-test.sh b/test/shell.d/yoga-slim7x-hardware-test.sh new file mode 100644 index 00000000000..66b5b340310 --- /dev/null +++ b/test/shell.d/yoga-slim7x-hardware-test.sh @@ -0,0 +1,96 @@ +#!/bin/bash + +set -euo pipefail + +source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" + +setup="$ROOT/install/hardware/lenovo/yoga-slim7x.sh" +starter="$ROOT/install/hardware/lenovo/start-yoga-slim7x-remoteprocs.sh" +scratch=$(mktemp -d) +trap 'rm -rf "$scratch"' EXIT + +bash -n "$setup" "$starter" || fail "Yoga Slim 7x hardware scripts have valid syntax" + +matching="$scratch/matching" +mkdir -p "$matching" +printf 'qcom,x1e80100\0lenovo,yoga-slim7x\0' >"$matching/compatible" +( + omarchy-hw-qualcomm-soc() { return 0; } + omarchy-hw-match() { return 1; } + systemctl() { printf '%s\n' "$*" >>"$matching/systemctl.log"; } + + OMARCHY_YOGA_COMPATIBLE_PATH="$matching/compatible" \ + OMARCHY_YOGA_MODULES_LOAD_DIR="$matching/modules-load.d" \ + OMARCHY_YOGA_MKINITCPIO_DIR="$matching/mkinitcpio.conf.d" \ + OMARCHY_YOGA_LIMINE_CONFIG_DIR="$matching/limine-entry-tool.d" \ + OMARCHY_YOGA_SYSTEMD_DIR="$matching/systemd" \ + source "$setup" +) + +grep -Fxq 'scmi-cpufreq' "$matching/modules-load.d/yoga-slim7x.conf" || + fail "Yoga Slim 7x setup loads its SCMI CPU-frequency driver" +grep -Fxq 'MODULES+=(i2c-hid-of qrtr ps883x pmic_glink_altmode)' \ + "$matching/mkinitcpio.conf.d/yoga-slim7x-initramfs.conf" || + fail "Yoga Slim 7x setup initializes the keyboard and display in the initramfs" +grep -Fq '/usr/lib/firmware/qcom/gen70500_sqe.fw' \ + "$matching/mkinitcpio.conf.d/yoga-slim7x-initramfs.conf" || + fail "Yoga Slim 7x setup includes its display firmware in the initramfs" +grep -Fxq 'KERNEL_CMDLINE[default]+=" initcall_blacklist=simpledrm_platform_driver_init"' \ + "$matching/limine-entry-tool.d/yoga-slim7x.conf" || + fail "Yoga Slim 7x setup defers display ownership to the native driver" +grep -Fq 'ConditionPathExists=!/etc/modprobe.d/qualcomm-adsp-nofw.conf' \ + "$matching/systemd/yoga-slim7x-remoteprocs.service" || + fail "Yoga Slim 7x skips DSP startup when the generic firmware leaf blacklists it" +if grep -Fq 'systemd-udev-settle.service' "$matching/systemd/yoga-slim7x-remoteprocs.service"; then + fail "Yoga Slim 7x DSP startup does not wait for all udev devices" +fi +grep -Fxq 'enable yoga-slim7x-remoteprocs.service' "$matching/systemctl.log" || + fail "Yoga Slim 7x enables its remote processor service" + +nonmatching="$scratch/nonmatching" +mkdir -p "$nonmatching" +printf 'qcom,x1e80100\0hp,elitebook-ultra-g1q\0' >"$nonmatching/compatible" +( + omarchy-hw-qualcomm-soc() { return 0; } + omarchy-hw-match() { return 1; } + systemctl() { fail "nonmatching Qualcomm hardware does not enable Yoga services"; } + + OMARCHY_YOGA_COMPATIBLE_PATH="$nonmatching/compatible" \ + OMARCHY_YOGA_MODULES_LOAD_DIR="$nonmatching/modules-load.d" \ + OMARCHY_YOGA_MKINITCPIO_DIR="$nonmatching/mkinitcpio.conf.d" \ + OMARCHY_YOGA_LIMINE_CONFIG_DIR="$nonmatching/limine-entry-tool.d" \ + OMARCHY_YOGA_SYSTEMD_DIR="$nonmatching/systemd" \ + source "$setup" +) + +[[ ! -e $nonmatching/modules-load.d/yoga-slim7x.conf ]] || + fail "nonmatching Qualcomm hardware does not get Yoga CPU setup" +[[ ! -e $nonmatching/mkinitcpio.conf.d/yoga-slim7x-initramfs.conf ]] || + fail "nonmatching Qualcomm hardware does not get Yoga initramfs setup" +[[ ! -e $nonmatching/limine-entry-tool.d/yoga-slim7x.conf ]] || + fail "nonmatching Qualcomm hardware does not get Yoga boot parameters" +[[ ! -e $nonmatching/systemd/yoga-slim7x-remoteprocs.service ]] || + fail "nonmatching Qualcomm hardware does not get Yoga services" + +remoteprocs="$scratch/remoteproc" +mkdir -p "$remoteprocs/remoteproc0" "$remoteprocs/remoteproc1" "$remoteprocs/remoteproc2" +printf 'qcom/x1e80100/LENOVO/83ED/qcadsp8380.mbn\n' >"$remoteprocs/remoteproc0/firmware" +printf 'offline\n' >"$remoteprocs/remoteproc0/state" +printf 'qcom/x1e80100/LENOVO/83ED/qccdsp8380.mbn\n' >"$remoteprocs/remoteproc1/firmware" +printf 'offline\n' >"$remoteprocs/remoteproc1/state" +printf 'unrelated.mbn\n' >"$remoteprocs/remoteproc2/firmware" +printf 'offline\n' >"$remoteprocs/remoteproc2/state" + +OMARCHY_YOGA_REMOTEPROC_ROOT="$remoteprocs" \ + OMARCHY_YOGA_REMOTEPROC_ATTEMPTS=1 \ + OMARCHY_YOGA_REMOTEPROC_SLEEP=0 \ + bash "$starter" + +[[ $(<"$remoteprocs/remoteproc0/state") == start ]] || + fail "Yoga Slim 7x helper starts the audio DSP by firmware identity" +[[ $(<"$remoteprocs/remoteproc1/state") == start ]] || + fail "Yoga Slim 7x helper starts the compute DSP by firmware identity" +[[ $(<"$remoteprocs/remoteproc2/state") == offline ]] || + fail "Yoga Slim 7x helper leaves unrelated remote processors alone" + +pass "Yoga Slim 7x adds only its board-specific keyboard, display, CPU and DSP setup"