From fe3e0da51d28aca18c7e715dc35f480304ff6627 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Sat, 20 Mar 2021 19:46:52 +0100 Subject: [PATCH] packages: add device_manager A component for hardware detection and driver instantiation. --- nixos-modules/eris/rom-fs.nix | 32 +------ nixos-modules/eris/rom-vfs.dhall | 8 +- nixos-modules/file-systems.nix | 4 +- nixos-modules/hardware/ahci.nix | 39 +-------- nixos-modules/hardware/default.nix | 95 +++++++++++++++++++- nixos-modules/hardware/usb.nix | 129 +++++++++------------------- nixos-modules/qemu-vm.nix | 7 +- packages/default.nix | 2 + packages/device_manager/default.nix | 33 +++++++ 9 files changed, 185 insertions(+), 164 deletions(-) create mode 100644 packages/device_manager/default.nix diff --git a/nixos-modules/eris/rom-fs.nix b/nixos-modules/eris/rom-fs.nix index 9e0228e..527d325 100644 --- a/nixos-modules/eris/rom-fs.nix +++ b/nixos-modules/eris/rom-fs.nix @@ -3,37 +3,6 @@ { config = lib.mkIf (config.genode.boot.storeBackend == "fs") { - genode.core.children.part_block = { - package = pkgs.genodePackages.part_block; - configFile = pkgs.writeText "part_block.dhall" '' - let Genode = env:DHALL_GENODE - - let Init = Genode.Init - - in λ(binary : Text) -> Init.Child.flat - Init.Child.Attributes::{ - , binary - , resources = Init.Resources::{ ram = Genode.units.MiB 8 } - , config = Init.Config::{ - , attributes = toMap { ignore_mbr = "yes" } - , policies = - [ Init.Config.Policy::{ - , service = "Block" - , label = Init.LabelSelector.prefix "eris_vfs" - , attributes = toMap - { partition = "${ - toString config.fileSystems."/".block.partition - }" - , writeable = "yes" - , TODO = "select by partition UUID" - } - } - ] - } - } - ''; - }; - genode.core.children.eris_vfs = let vfsRump = lib.getEris' "lib" pkgs.genodePackages.rump "vfs_rump.lib.so"; in { @@ -45,6 +14,7 @@ let VFS = Genode.VFS in ${./rom-vfs.dhall} + ${../partition-type} Genode.Init.Resources::{ caps = 256, ram = Genode.units.MiB 16 } ( VFS.vfs [ VFS.leafAttrs diff --git a/nixos-modules/eris/rom-vfs.dhall b/nixos-modules/eris/rom-vfs.dhall index d11978b..4f22938 100644 --- a/nixos-modules/eris/rom-vfs.dhall +++ b/nixos-modules/eris/rom-vfs.dhall @@ -4,7 +4,8 @@ let Init = Genode.Init let Child = Init.Child -in λ(resources : Init.Resources.Type) → +in λ(partitionType : Text) → + λ(resources : Init.Resources.Type) → λ(vfsConfig : Genode.Prelude.XML.Type) → λ(binary : Text) → Child.flat @@ -21,4 +22,9 @@ in λ(resources : Init.Resources.Type) → } ] } + , routes = + [ { service = Init.Service::{ name = "Block" } + , route = Init.Route.child "drivers" (Some partitionType) + } + ] } diff --git a/nixos-modules/file-systems.nix b/nixos-modules/file-systems.nix index 4b9ce65..37828b3 100644 --- a/nixos-modules/file-systems.nix +++ b/nixos-modules/file-systems.nix @@ -25,8 +25,8 @@ with lib; { hardware.genode.ahci.enable = any (fs: fs.block.driver == "ahci") (attrValues config.fileSystems); - hardware.genode.usb.storage.enable = - any (fs: fs.block.driver == "usb") (attrValues config.fileSystems); + hardware.genode.usb.storage.enable = lib.mkDefault + (any (fs: fs.block.driver == "usb") (attrValues config.fileSystems)); }; } diff --git a/nixos-modules/hardware/ahci.nix b/nixos-modules/hardware/ahci.nix index b754dd3..19305e5 100644 --- a/nixos-modules/hardware/ahci.nix +++ b/nixos-modules/hardware/ahci.nix @@ -5,6 +5,7 @@ with lib; { options.hardware.genode.ahci = { enable = lib.mkEnableOption "AHCI (SATA) block driver"; + atapiSupport = lib.mkEnableOption "ATAPI support"; }; config = let cfg = config.hardware.genode.ahci; @@ -16,7 +17,7 @@ with lib; in Genode.Init.Config.Policy::{ , service = "Platform" - , label = Genode.Init.LabelSelector.prefix "ahci_drv" + , label = Genode.Init.LabelSelector.prefix "drivers -> ahci" , content = [ Genode.Prelude.XML.leaf { name = "pci", attributes = toMap { class = "AHCI" } } @@ -24,42 +25,6 @@ with lib; } ''); - genode.core.children.ahci_drv = lib.mkIf cfg.enable { - package = pkgs.genodePackages.ahci_drv; - configFile = pkgs.writeText "ahci_drv.dhall" '' - let Genode = env:DHALL_GENODE - - let Init = Genode.Init - - in λ(binary : Text) -> Init.Child.flat - Init.Child.Attributes::{ - , binary - , resources = Init.Resources::{ - , caps = 400 - , ram = Genode.units.MiB 10 - , constrainPhys = True - } - , romReports = [ { local = "ports", route = "ahci_ports" } ] - , routes = - [ Init.ServiceRoute.parent "IRQ" - , Init.ServiceRoute.parent "IO_MEM" - , Init.ServiceRoute.parent "IO_PORT" - ] - , config = Init.Config::{ - , policies = - [ Init.Config.Policy::{ - , service = "Block" - , label = Init.LabelSelector.prefix "part_block" - , attributes = toMap { device = "${ - toString config.fileSystems."/".block.device - }", writeable = "yes" } - } - ] - } - } - ''; - }; - }; } diff --git a/nixos-modules/hardware/default.nix b/nixos-modules/hardware/default.nix index a6efb52..38fec43 100644 --- a/nixos-modules/hardware/default.nix +++ b/nixos-modules/hardware/default.nix @@ -14,7 +14,50 @@ with lib; ''; }; - config = { + config = let + ahciEris = lib.getEris "bin" pkgs.genodePackages.ahci_drv; + partBlockEris = lib.getEris "bin" pkgs.genodePackages.part_block; + + usbEris = lib.attrsets.mapAttrs (_: lib.getEris "bin") { + inherit (pkgs.genodePackages) usb_block_drv usb_drv; + }; + + ahciConfig = with config.hardware.genode.ahci; + lib.optionalString enable '' + , ahci_driver = Some ${ + lib.generators.toDhall { + binary = ahciEris.cap; + atapi = atapiSupport; + } + } + ''; + + usbConfig = with config.hardware.genode.usb; + lib.optionalString enable '' + , usb_block = Some { binary = "${usbEris.usb_block_drv.cap}" } + , usb_driver = Some ${ + lib.generators.toDhall { + binary = usbEris.usb_drv.cap; + bios_handoff = biosHandoff; + ehci = ehciSupport; + ohci = ohciSupport; + uhci = uhciSupport; + xhci = xhciSupport; + } + } + ''; + + managerConfig = pkgs.writeText "device_manager.dhall" '' + let Manager = ${pkgs.genodePackages.device_manager.dhall}/package.dhall + + in Manager.toChildAttributes + Manager::{ + , part_block.binary = "${partBlockEris.cap}" + ${ahciConfig} + ${usbConfig} + } + ''; + in { genode.core.children.acpi_drv = { package = pkgs.genodePackages.acpi_drv; @@ -70,12 +113,60 @@ with lib; , Init.ServiceRoute.parent "IO_PORT" ] , config = Init.Config::{ - , policies = [ ${toString policies} ] : List Init.Config.Policy.Type + , policies = [ ${ + toString policies + } ] : List Init.Config.Policy.Type } } ''; }; + genode.core.children.device_manager = { + package = pkgs.genodePackages.device_manager; + configFile = pkgs.writeText "device_manager.dhall" '' + let Genode = env:DHALL_GENODE + + in λ(cap : Text) → + Genode.Init.Child.flat + ( (${managerConfig}).device_manager + ⫽ { binary = cap + , resources = Genode.Init.Resources::{ + , caps = 256 + , ram = Genode.units.MiB 8 + } + } + ) + ''; + }; + + genode.core.children.drivers = { + package = pkgs.genodePackages.init; + extraErisInputs = [ partBlockEris ] ++ + lib.optional config.hardware.genode.ahci.enable ahciEris + ++ lib.optionals config.hardware.genode.usb.enable + (builtins.attrValues usbEris); + configFile = pkgs.writeText "drivers.dhall" '' + let Genode = env:DHALL_GENODE + + let childAttrs = (${managerConfig}).drivers + + in λ(cap : Text) → + Genode.Init.Child.flat + ( childAttrs + ⫽ { binary = cap + , config = + childAttrs.config + with policies = + [ Genode.Init.Config.Policy::{ + , label = Genode.Init.LabelSelector.none + , service = "Block" + } + ] + } + ) + ''; + }; + }; } diff --git a/nixos-modules/hardware/usb.nix b/nixos-modules/hardware/usb.nix index 1d33f46..bcacd24 100644 --- a/nixos-modules/hardware/usb.nix +++ b/nixos-modules/hardware/usb.nix @@ -3,22 +3,52 @@ with lib; { - options.hardware.genode.usb = { + options.hardware.genode.usb = let + mkEnableOption' = text: default: + lib.mkEnableOption text // { + inherit default; + }; + in { enable = lib.mkEnableOption "USB driver"; storage.enable = lib.mkEnableOption "USB mass storage driver"; - ehciSupport = lib.mkEnableOption "EHCI support" // { default = true; }; - ohciSupport = lib.mkEnableOption "OHCI support" // { default = true; }; - uhciSupport = lib.mkEnableOption "UHCI support" // { default = false; }; - xhciSupport = lib.mkEnableOption "XHCI support" // { default = true; }; + biosHandoff = mkEnableOption' "perform the BIOS handoff procedure" true; + + ehciSupport = mkEnableOption' "EHCI support" true; + ohciSupport = mkEnableOption' "OHCI support" true; + uhciSupport = mkEnableOption' "UHCI support" false; + xhciSupport = mkEnableOption' "XHCI support" true; }; - config = let cfg = config.hardware.genode.usb; + config = let + cfg = config.hardware.genode.usb; + + usbEris = lib.attrsets.mapAttrs (_: lib.getEris "bin") { + inherit (pkgs.genodePackages) part_block usb_block_drv usb_drv; + }; + + managerConfig = pkgs.writeText "usb_device_manager.dhall" '' + let Manager = ${pkgs.genodePackages.usb_device_manager.dhall}/package.dhall + + in Manager.toChildAttributes + Manager::{ + , part_block.binary = "${usbEris.part_block.cap}" + , usb_block.binary = "${usbEris.usb_block_drv.cap}" + , usb_driver = + { binary = "${usbEris.usb_drv.cap}" + , bios_handoff = True + , ehci = True + , ohci = False + , uhci = False + , xhci = False + } + } + ''; in { - hardware.genode.usb.enable = cfg.storage.enable; + hardware.genode.usb.enable = lib.mkDefault cfg.storage.enable; hardware.genode.platform.policies = lib.optional cfg.enable (builtins.toFile ("usb.platform-policy.dhall") '' @@ -26,7 +56,7 @@ with lib; in Genode.Init.Config.Policy::{ , service = "Platform" - , label = Genode.Init.LabelSelector.prefix "usb_drv" + , label = Genode.Init.LabelSelector.prefix "drivers -> usb" , content = [ Genode.Prelude.XML.leaf { name = "pci", attributes = toMap { class = "USB" } } @@ -34,91 +64,10 @@ with lib; } ''); - genode.init.children.usb_drv = lib.mkIf cfg.enable { - binary = "${pkgs.genodePackages.usb_drv}/bin/usb_drv"; - configFile = let toYesNo = b: if b then "yes" else "no"; - in builtins.toFile "usb_drv.dhall" '' - let Genode = env:DHALL_GENODE - - let XML = Genode.Prelude.XML - - let Init = Genode.Init - - in λ(binary : Text) → - Init.Child.flat - Init.Child.Attributes::{ - , binary - , resources = Init.Resources::{ caps = 256, ram = Genode.units.MiB 12 } - , romReports = let local = "devices" in [ { local, route = local } ] - , routes = [ Init.ServiceRoute.parent "IO_MEM" ] - , config = - let storagePolicy = - Init.Config.Policy::{ - , service = "Usb" - , label = Init.LabelSelector.prefix "usb_block_drv" - , attributes = toMap { class = "8" } - , diag = Some True - } - - in Init.Config::{ - , attributes = toMap - { ehci = "${toYesNo cfg.ehciSupport}" - , ohci = "${toYesNo cfg.ohciSupport}" - , uhci = "${toYesNo cfg.uhciSupport}" - , xhci = "${toYesNo cfg.xhciSupport}" - } - , content = - [ XML.element - { name = "raw" - , attributes = XML.emptyAttributes - , content = - [ XML.leaf - { name = "report" - , attributes = toMap { devices = "yes" } - } - , Init.Config.Policy.toXML storagePolicy - ] - } - ] - , policies = [ storagePolicy ] - } - } - ''; - }; - - genode.core.children.usb_block_drv = - mkIf config.hardware.genode.usb.storage.enable { - binary = pkgs.genodePackages.usb_block_drv; - configFile = builtins.toFile "usb_block_drv.dhall" '' - let Genode = env:DHALL_GENODE - - let Init = Genode.Init - - in λ(binary : Text) → - Init.Child.flat - Init.Child.Attributes::{ - , binary - , resources = Init.Resources::{ caps = 256, ram = Genode.units.MiB 4 } - , config = Init.Config::{ - , attributes = toMap { writeable = "yes" } - , policies = - [ Init.Config.Policy::{ - , service = "Block" - , label = Init.LabelSelector.prefix "part_block" - } - ] - } - } - ''; - }; - virtualisation.qemu.options = lib.optional cfg.enable (lib.optional (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) "-usb" ++ lib.optional (pkgs.stdenv.isAarch32 || pkgs.stdenv.isAarch64) - "-device usb-ehci,id=usb0") ++ lib.optional cfg.storage.enable [ - "-drive id=usbdisk,file=${config.system.build.bootDriveImage},if=none,readonly" - "-device usb-storage,drive=usbdisk" - ]; + "-device usb-ehci,id=usb0"); }; diff --git a/nixos-modules/qemu-vm.nix b/nixos-modules/qemu-vm.nix index 8cce9f7..f08a2a3 100644 --- a/nixos-modules/qemu-vm.nix +++ b/nixos-modules/qemu-vm.nix @@ -50,7 +50,12 @@ let -smp ${toString config.virtualisation.cores} \ ${concatStringsSep " " config.virtualisation.qemu.networkingOptions} \ ${toString config.virtualisation.qemu.options} \ - $NIX_DISK_IMAGE \ + ${ + if config.hardware.genode.usb.storage.enable then + "-drive id=usbdisk,if=none,file=$NIX_DISK_IMAGE -device usb-storage,drive=usbdisk" + else + "$NIX_DISK_IMAGE" + } \ $QEMU_OPTS \ "$@" ''; diff --git a/packages/default.nix b/packages/default.nix index 4f9db57..248f809 100644 --- a/packages/default.nix +++ b/packages/default.nix @@ -29,6 +29,8 @@ in upstream // { block_router = callPackage ./block_router { }; + device_manager = callPackage ./device_manager { }; + dhallGenode = dhallPackages.genode; nic_bus = callPackage ./nic_bus { }; diff --git a/packages/device_manager/default.nix b/packages/device_manager/default.nix new file mode 100644 index 0000000..1ddbefb --- /dev/null +++ b/packages/device_manager/default.nix @@ -0,0 +1,33 @@ +{ lib, stdenv, fetchgit, nim, nimblePackages }: + +stdenv.mkDerivation rec { + pname = "device_manager"; + version = "0.0"; + outputs = [ "out" "dhall" ]; + + src = fetchgit { + url = "https://git.sr.ht/~ehmry/${pname}"; + rev = "6770ca1d2b08ae0cc9954db797cdd484bc0dc554"; + sha256 = "1c8pb6blay6szfxwpss81d39258vrfqjvycaiis71a5d0anzs1ap"; + }; + + nimFlags = with nimblePackages; + map (lib: "--path:${lib}/src") [ genode ] ++ [ "-d:posix" ]; + + nativeBuildInputs = [ nim ]; + + preHook = '' + export HOME="$NIX_BUILD_TOP" + ''; + + buildPhase = '' + runHook preBuild + nim cpp $nimFlags src/$pname + runHook postBuild + ''; + + installPhase = '' + install -Dt $out/bin src/$pname + install -Dt $dhall config/package.dhall + ''; +}