{ config, pkgs, lib, ... }: with lib; { options.hardware.genode.usb = { 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; }; }; config = let cfg = config.hardware.genode.usb; in { hardware.genode.usb.storage.enable = config.genode.boot.storeBackend == "usb"; hardware.genode.usb.enable = cfg.storage.enable; hardware.genode.platform.policies = lib.optional cfg.enable (builtins.toFile ("usb.platform-policy.dhall") '' let Genode = env:DHALL_GENODE in Genode.Init.Config.Policy::{ , service = "Platform" , label = Genode.Init.LabelSelector.prefix "usb_drv" , content = [ Genode.Prelude.XML.leaf { name = "pci", attributes = toMap { class = "USB" } } ] } ''); genode.init.children.usb_drv = lib.mkIf cfg.enable { inputs = [ pkgs.genodePackages.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 Init.Child.flat Init.Child.Attributes::{ , binary = "usb_drv" , 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 { inputs = [ pkgs.genodePackages.usb_block_drv ]; configFile = builtins.toFile "usb_block_drv.dhall" '' let Genode = env:DHALL_GENODE let XML = Genode.Prelude.XML let Init = Genode.Init in Init.Child.flat Init.Child.Attributes::{ , binary = "usb_block_drv" , 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"); }; }