diff --git a/hydrajobs.nix b/hydrajobs.nix index 540c7dab9..8cbfdbffd 100644 --- a/hydrajobs.nix +++ b/hydrajobs.nix @@ -8,6 +8,8 @@ generic-x86_64-debug.x86_64-linux = self.packages.x86_64-linux.generic-x86_64-debug; lenovo-x1-carbon-gen11-debug.x86_64-linux = self.packages.x86_64-linux.lenovo-x1-carbon-gen11-debug; lenovo-x1-carbon-gen11-gnome-debug.x86_64-linux = self.packages.x86_64-linux.lenovo-x1-carbon-gen11-gnome-debug; + lenovo-p16-gen2-debug.x86_64-linux = self.packages.x86_64-linux.lenovo-p16-gen2-debug; + lenovo-p16-gen2-gnome-debug.x86_64-linux = self.packages.x86_64-linux.lenovo-p16-gen2-gnome-debug; nvidia-jetson-orin-agx-debug.aarch64-linux = self.packages.aarch64-linux.nvidia-jetson-orin-agx-debug; nvidia-jetson-orin-nx-debug.aarch64-linux = self.packages.aarch64-linux.nvidia-jetson-orin-nx-debug; intel-vm-debug.x86_64-linux = self.packages.x86_64-linux.vm-debug; diff --git a/targets/default.nix b/targets/default.nix index f41707990..36daceb60 100644 --- a/targets/default.nix +++ b/targets/default.nix @@ -16,6 +16,7 @@ lib.foldr lib.recursiveUpdate {} [ (import ./vm.nix {inherit self lib nixos-generators microvm;}) (import ./generic-x86_64.nix {inherit self lib nixos-generators nixos-hardware microvm;}) (import ./lenovo-x1-carbon.nix {inherit self lib nixos-generators nixos-hardware microvm;}) + (import ./lenovo-p16.nix {inherit self lib nixos-generators nixos-hardware microvm;}) (import ./imx8qm-mek.nix {inherit self lib nixos-generators nixos-hardware microvm;}) (import ./microchip-icicle-kit.nix {inherit self lib nixpkgs nixos-hardware;}) ] diff --git a/targets/lenovo-p16.nix b/targets/lenovo-p16.nix new file mode 100644 index 000000000..9b60417e2 --- /dev/null +++ b/targets/lenovo-p16.nix @@ -0,0 +1,282 @@ +# Copyright 2022-2023 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +# +# Generic x86_64 computer -target +{ + self, + lib, + nixos-generators, + nixos-hardware, + microvm, +}: let + name = "lenovo-p16-gen2"; + system = "x86_64-linux"; + formatModule = nixos-generators.nixosModules.raw-efi; + lenovo-p16 = variant: extraModules: let + netvmExtraModules = [ + { + microvm.devices = lib.mkForce [ + { + bus = "pci"; + path = "0000:00:14.3"; + } + ]; + + # For WLAN firmwares + hardware.enableRedistributableFirmware = true; + + networking.wireless = { + enable = true; + + #networks."ssid".psk = "psk"; + }; + } + ]; + guivmConfig = hostConfiguration.config.ghaf.virtualization.microvm.guivm; + guivmExtraModules = [ + { + # Early KMS needed for GNOME to work inside GuiVM + boot.initrd.kernelModules = ["i915"]; + + microvm.qemu.extraArgs = [ + # Touchpad and keyboard + "-device" + "virtio-input-host-pci,evdev=/dev/input/by-path/platform-i8042-serio-0-event-kbd" + "-device" + "virtio-input-host-pci,evdev=/dev/mouse" + "-device" + "virtio-input-host-pci,evdev=/dev/touchpad" + # Trackpoint (red button/joystick) + "-device" + "virtio-input-host-pci,evdev=/dev/input/by-path/platform-i8042-serio-1-event-mouse" + # Lid button + "-device" + "button" + # Battery + "-device" + "battery" + # AC adapter + "-device" + "acad" + ]; + microvm.devices = [ + { + bus = "pci"; + path = "0000:00:02.0"; + } + ]; + } + ({pkgs, ...}: { + ghaf.graphics.weston.launchers = [ + { + path = "${pkgs.openssh}/bin/ssh -i ${pkgs.waypipe-ssh}/keys/waypipe-ssh -o StrictHostKeyChecking=no 192.168.101.5 ${pkgs.waypipe}/bin/waypipe --vsock -s ${toString guivmConfig.waypipePort} server chromium --enable-features=UseOzonePlatform --ozone-platform=wayland"; + icon = "${pkgs.weston}/share/weston/icon_editor.png"; + } + + { + path = "${pkgs.openssh}/bin/ssh -i ${pkgs.waypipe-ssh}/keys/waypipe-ssh -o StrictHostKeyChecking=no 192.168.101.6 ${pkgs.waypipe}/bin/waypipe --vsock -s ${toString guivmConfig.waypipePort} server gala --enable-features=UseOzonePlatform --ozone-platform=wayland"; + icon = "${pkgs.weston}/share/weston/icon_editor.png"; + } + + { + path = "${pkgs.openssh}/bin/ssh -i ${pkgs.waypipe-ssh}/keys/waypipe-ssh -o StrictHostKeyChecking=no 192.168.101.7 ${pkgs.waypipe}/bin/waypipe --vsock -s ${toString guivmConfig.waypipePort} server zathura"; + icon = "${pkgs.weston}/share/weston/icon_editor.png"; + } + ]; + }) + ]; + hostConfiguration = lib.nixosSystem { + inherit system; + specialArgs = {inherit lib;}; + modules = + [ + microvm.nixosModules.host + ../modules/host + ../modules/virtualization/microvm/microvm-host.nix + ../modules/virtualization/microvm/netvm.nix + ../modules/virtualization/microvm/guivm.nix + ../modules/virtualization/microvm/appvm.nix + ({ + pkgs, + lib, + ... + }: { + services.udev.extraRules = '' + # Laptop keyboard + SUBSYSTEM=="input",ATTRS{name}=="AT Translated Set 2 keyboard",GROUP="kvm" + # Laptop touchpad + SUBSYSTEM=="input",ATTRS{name}=="ELAN0685:00 04F3:320B Mouse",KERNEL=="event*",GROUP="kvm",SYMLINK+="mouse" + SUBSYSTEM=="input",ATTRS{name}=="ELAN0685:00 04F3:320B Touchpad",KERNEL=="event*",GROUP="kvm",SYMLINK+="touchpad" + # Laptop TrackPoint + SUBSYSTEM=="input",ATTRS{name}=="TPPS/2 Synaptics TrackPoint",GROUP="kvm" + # Lenovo Integrated Webcam + SUBSYSTEM=="usb",ATTR{idVendor}=="30c9",ATTR{idProduct}=="0050",GROUP="kvm" + ''; + + # Enable pulseaudio support for host as a service + sound.enable = true; + hardware.pulseaudio.enable = true; + hardware.pulseaudio.systemWide = true; + nixpkgs.config.pulseaudio = true; + # Add systemd to require pulseaudio before starting chromium-vm + systemd.services."microvm@chromium-vm".after = ["pulseaudio.service"]; + systemd.services."microvm@chromium-vm".requires = ["pulseaudio.service"]; + + # Allow microvm user to access pulseaudio + hardware.pulseaudio.extraConfig = "load-module module-combine-sink module-native-protocol-unix auth-anonymous=1"; + users.extraUsers.microvm.extraGroups = ["audio" "pulse-access"]; + + ghaf = { + hardware.x86_64.common.enable = true; + + virtualization.microvm-host.enable = true; + host.networking.enable = true; + virtualization.microvm.netvm = { + enable = true; + extraModules = netvmExtraModules; + }; + virtualization.microvm.guivm = { + enable = true; + extraModules = guivmExtraModules; + }; + virtualization.microvm.appvm = { + enable = true; + vms = [ + { + name = "chromium"; + packages = [pkgs.chromium pkgs.pamixer]; + ipAddress = "192.168.101.5/24"; + macAddress = "02:00:00:03:05:01"; + ramMb = 3072; + cores = 4; + extraModules = [ + { + # Enable pulseaudio for user ghaf + sound.enable = true; + hardware.pulseaudio.enable = true; + users.extraUsers.ghaf.extraGroups = ["audio"]; + nixpkgs.config.pulseaudio = true; + + microvm.qemu.extraArgs = [ + # Lenovo Integrated USB Webcam + "-device" + "qemu-xhci" + "-device" + "usb-host,vendorid=0x30c9,productid=0x0050" + # Connect sound device to hosts pulseaudio socket + "-audiodev" + "pa,id=pa1,server=unix:/run/pulse/native" + # Add HDA sound device to guest + "-device" + "intel-hda" + "-device" + "hda-duplex,audiodev=pa1" + ]; + microvm.devices = []; + } + ]; + } + { + name = "gala"; + packages = [pkgs.gala-app]; + ipAddress = "192.168.101.6/24"; + macAddress = "02:00:00:03:06:01"; + ramMb = 1536; + cores = 2; + } + { + name = "zathura"; + packages = [pkgs.zathura]; + ipAddress = "192.168.101.7/24"; + macAddress = "02:00:00:03:07:01"; + ramMb = 512; + cores = 1; + } + ]; + extraModules = [ + ../overlays/custom-packages.nix + ]; + }; + + # Enable all the default UI applications + profiles = { + applications.enable = false; + }; + windows-launcher.enable = false; + }; + }) + + ({config, ...}: { + ghaf.installer = { + enable = true; + imgModules = [ + nixos-generators.nixosModules.raw-efi + ]; + enabledModules = ["flushImage"]; + installerCode = '' + echo "Starting flushing..." + if sudo dd if=${config.system.build.${config.formatAttr}}/nixos.img of=/dev/${config.ghaf.installer.installerModules.flushImage.providedVariables.deviceName} conv=sync bs=4K status=progress; then + sync + echo "Flushing finished successfully!" + echo "Now you can detach installation device and reboot to ghaf." + else + echo "Some error occured during flushing process, exit code: $?." + exit + fi + ''; + }; + }) + + formatModule + + #TODO: how to handle the majority of laptops that need a little + # something extra? + # SEE: https://github.com/NixOS/nixos-hardware/blob/master/flake.nix + # nixos-hardware.nixosModules.lenovo-thinkpad-x1-10th-gen + + { + boot.kernelParams = [ + "intel_iommu=on,igx_off,sm_on" + "iommu=pt" + # Passthrough Intel WiFi card 8086:7a70 + # Passthrough Intel GPU 8086:4688 + "vfio-pci.ids=8086:7a70,8086:4688" + ]; + boot.initrd.availableKernelModules = ["nvme"]; + } + ] + ++ (import ../modules/module-list.nix) + ++ extraModules; + }; + in { + inherit hostConfiguration; + name = "${name}-${variant}"; + package = hostConfiguration.config.system.build.${hostConfiguration.config.formatAttr}; + }; + debugModules = [ + ../modules/development/usb-serial.nix + { + ghaf.development.usb-serial.enable = true; + ghaf.profiles.debug.enable = true; + } + ]; + releaseModules = [ + { + ghaf.profiles.release.enable = true; + } + ]; + gnomeModules = [{ghaf.virtualization.microvm.guivm.extraModules = [{ghaf.profiles.graphics.compositor = "gnome";}];}]; + targets = [ + (lenovo-p16 "debug" debugModules) + (lenovo-p16 "release" releaseModules) + (lenovo-p16 "gnome-debug" (gnomeModules ++ debugModules)) + (lenovo-p16 "gnome-release" (gnomeModules ++ releaseModules)) + ]; +in { + nixosConfigurations = + builtins.listToAttrs (map (t: lib.nameValuePair t.name t.hostConfiguration) targets); + packages = { + x86_64-linux = + builtins.listToAttrs (map (t: lib.nameValuePair t.name t.package) targets); + }; +}