2020-11-01 20:21:27 +01:00
|
|
|
{ config, pkgs, lib, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
{
|
2020-11-10 16:01:58 +01:00
|
|
|
options = {
|
2020-11-01 20:21:27 +01:00
|
|
|
|
2020-11-10 16:01:58 +01:00
|
|
|
networking.interfaces = lib.mkOption {
|
|
|
|
type = with types;
|
|
|
|
attrsOf (submodule ({ ... }: {
|
|
|
|
options.genode = {
|
|
|
|
|
2020-12-10 19:27:53 +01:00
|
|
|
driver = mkOption {
|
|
|
|
type = types.enum [ "ipxe" "virtio" ];
|
|
|
|
description = "Nic driver to use for this interface.";
|
|
|
|
};
|
2020-11-10 16:01:58 +01:00
|
|
|
|
|
|
|
stack = mkOption {
|
|
|
|
type = with types; nullOr (enum [ "lwip" "lxip" ]);
|
|
|
|
default = "lwip";
|
2020-12-10 19:27:53 +01:00
|
|
|
description = "IP stack to use for this interface.";
|
2020-11-10 16:01:58 +01:00
|
|
|
};
|
2020-11-01 20:21:27 +01:00
|
|
|
|
|
|
|
};
|
2020-11-10 16:01:58 +01:00
|
|
|
}));
|
|
|
|
};
|
|
|
|
|
|
|
|
hardware.genode.platform.policies = lib.mkOption {
|
|
|
|
type = with types; listOf path;
|
|
|
|
default = [ ];
|
|
|
|
description = ''
|
|
|
|
List of policies to append to the Genode platform driver.
|
|
|
|
Type is Init.Config.Policy.Type.
|
|
|
|
'';
|
|
|
|
};
|
2020-11-01 20:21:27 +01:00
|
|
|
|
2020-12-10 19:27:53 +01:00
|
|
|
hardware.genode = {
|
|
|
|
|
|
|
|
usb.enable = lib.mkEnableOption "USB driver";
|
|
|
|
usb.storage.enable = lib.mkEnableOption "USB mass storage driver";
|
|
|
|
|
|
|
|
framebuffer = {
|
|
|
|
enable = lib.mkEnableOption "framebuffer driver";
|
|
|
|
driver = mkOption {
|
|
|
|
type = types.enum [ "boot" "vesa" ];
|
|
|
|
default = "vesa";
|
|
|
|
};
|
|
|
|
};
|
2020-12-03 12:48:07 +01:00
|
|
|
|
2020-12-10 19:27:53 +01:00
|
|
|
};
|
2020-12-03 12:48:07 +01:00
|
|
|
|
2020-11-01 20:21:27 +01:00
|
|
|
};
|
|
|
|
|
2020-11-10 16:01:58 +01:00
|
|
|
config = {
|
|
|
|
|
|
|
|
assertions = with builtins;
|
|
|
|
let
|
|
|
|
addrCheck = name: interface: {
|
|
|
|
assertion = lessThan (length interface.ipv4.addresses) 2;
|
|
|
|
message = "Genode interfaces do not support multihoming.";
|
2020-11-01 20:21:27 +01:00
|
|
|
};
|
2020-11-10 16:01:58 +01:00
|
|
|
routeCheck = name: interface: {
|
|
|
|
assertion = lessThan (length interface.ipv4.routes) 2;
|
|
|
|
message = "Genode interfaces do not support multiple routes.";
|
2020-11-01 20:21:27 +01:00
|
|
|
};
|
2020-11-10 16:01:58 +01:00
|
|
|
in lib.mapAttrsToList addrCheck config.networking.interfaces
|
|
|
|
++ lib.mapAttrsToList routeCheck config.networking.interfaces;
|
|
|
|
|
2020-12-10 19:27:53 +01:00
|
|
|
hardware.genode.usb.storage.enable = config.genode.boot.storeBackend
|
2020-12-03 12:48:07 +01:00
|
|
|
== "usb";
|
|
|
|
|
2020-12-10 19:27:53 +01:00
|
|
|
hardware.genode.usb.enable = config.hardware.genode.usb.storage.enable;
|
2020-12-03 12:48:07 +01:00
|
|
|
|
2020-11-10 16:01:58 +01:00
|
|
|
hardware.genode.platform.policies = lib.lists.imap0 (i: name:
|
|
|
|
builtins.toFile (name + ".platform-policy.dhall") ''
|
2020-11-01 20:21:27 +01:00
|
|
|
let Genode = env:DHALL_GENODE
|
|
|
|
|
2020-11-10 16:01:58 +01:00
|
|
|
in Genode.Init.Config.Policy::{
|
|
|
|
, service = "Platform"
|
2020-12-03 12:48:07 +01:00
|
|
|
, label = Genode.Init.LabelSelector.prefix "nixos -> ${name}.driver"
|
2020-11-10 16:01:58 +01:00
|
|
|
, content =
|
|
|
|
[ Genode.Prelude.XML.leaf
|
|
|
|
{ name = "pci"
|
|
|
|
, attributes = toMap {
|
|
|
|
, class = "ETHERNET"
|
|
|
|
, index = "${toString i}"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
2020-12-03 12:48:07 +01:00
|
|
|
'') (builtins.attrNames config.networking.interfaces)
|
2020-12-10 19:27:53 +01:00
|
|
|
++ lib.optional config.hardware.genode.framebuffer.enable
|
|
|
|
(builtins.toFile ("framebuffer.platform-policy.dhall") ''
|
|
|
|
let Genode = env:DHALL_GENODE
|
|
|
|
|
|
|
|
in Genode.Init.Config.Policy::{
|
|
|
|
, service = "Platform"
|
|
|
|
, label = Genode.Init.LabelSelector.prefix "fb_drv"
|
|
|
|
, content =
|
|
|
|
[ Genode.Prelude.XML.leaf
|
|
|
|
{ name = "pci", attributes = toMap { class = "VGA" } }
|
|
|
|
]
|
|
|
|
}
|
|
|
|
'') ++ lib.optional config.hardware.genode.usb.enable
|
2020-12-03 12:48:07 +01:00
|
|
|
(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" } }
|
|
|
|
]
|
|
|
|
}
|
|
|
|
'');
|
2020-11-10 16:01:58 +01:00
|
|
|
|
|
|
|
genode.init.children = let
|
2020-11-01 20:21:27 +01:00
|
|
|
|
2020-11-10 16:01:58 +01:00
|
|
|
nics = mapAttrs' (name: interface:
|
|
|
|
let name' = name + ".driver";
|
|
|
|
in {
|
|
|
|
name = name';
|
|
|
|
value = let
|
|
|
|
binary = with pkgs.genodePackages;
|
|
|
|
{
|
|
|
|
ipxe = ipxe_nic_drv;
|
|
|
|
virtio = virtio_nic_drv;
|
|
|
|
}.${interface.genode.driver};
|
|
|
|
in {
|
|
|
|
inputs = [ binary ];
|
|
|
|
configFile = let
|
|
|
|
policies = if interface.genode.stack == null then
|
|
|
|
"[] : List Init.Config.Policy.Type"
|
|
|
|
else ''
|
|
|
|
[ Init.Config.Policy::{
|
|
|
|
, service = "Nic"
|
|
|
|
, label = Init.LabelSelector.prefix "${name}.sockets"
|
|
|
|
}
|
2020-11-01 20:21:27 +01:00
|
|
|
]
|
2020-11-10 16:01:58 +01:00
|
|
|
'';
|
|
|
|
in pkgs.writeText "${name'}.dhall" ''
|
|
|
|
let Genode = env:DHALL_GENODE
|
2020-11-01 20:21:27 +01:00
|
|
|
|
2020-11-10 16:01:58 +01:00
|
|
|
let Init = Genode.Init
|
2020-11-01 20:21:27 +01:00
|
|
|
|
2020-11-10 16:01:58 +01:00
|
|
|
in Init.Child.flat
|
|
|
|
Init.Child.Attributes::{
|
2020-12-10 19:27:53 +01:00
|
|
|
, binary = "${binary}/bin/${binary.pname}"
|
2020-11-10 16:01:58 +01:00
|
|
|
, resources = Init.Resources::{
|
|
|
|
, caps = 128
|
|
|
|
, ram = Genode.units.MiB 4
|
|
|
|
}
|
2020-12-03 12:48:07 +01:00
|
|
|
, routes = [
|
|
|
|
, Init.ServiceRoute.parent "IO_MEM"
|
|
|
|
, Init.ServiceRoute.parent "Platform"
|
|
|
|
]
|
2020-11-10 16:01:58 +01:00
|
|
|
, config = Init.Config::{
|
|
|
|
, attributes = toMap { verbose = "true" }
|
|
|
|
, policies = ${policies}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
}) config.networking.interfaces;
|
|
|
|
|
|
|
|
sockets = mapAttrs' (name: interface:
|
|
|
|
let name' = name + ".sockets";
|
|
|
|
in {
|
|
|
|
name = name';
|
|
|
|
value = if interface.genode.stack == null then
|
|
|
|
null
|
|
|
|
else {
|
|
|
|
inputs = with pkgs.genodePackages;
|
|
|
|
{
|
|
|
|
lwip = [ vfs_lwip ];
|
2020-11-12 19:37:16 +01:00
|
|
|
lxip = [ vfs_lxip ];
|
2020-11-10 16:01:58 +01:00
|
|
|
}.${interface.genode.stack};
|
|
|
|
configFile = let
|
|
|
|
binary = "${pkgs.genodePackages.vfs}/bin/vfs";
|
2020-11-12 19:37:16 +01:00
|
|
|
ram = {
|
|
|
|
lwip = 16;
|
|
|
|
lxip = 32;
|
|
|
|
}.${interface.genode.stack};
|
2020-11-10 16:01:58 +01:00
|
|
|
settings = with builtins;
|
|
|
|
lib.optionals (interface.ipv4.addresses != [ ])
|
|
|
|
(let addr = head interface.ipv4.addresses;
|
|
|
|
in [
|
|
|
|
{
|
|
|
|
name = "ip_addr";
|
|
|
|
value = addr.address;
|
|
|
|
}
|
|
|
|
{
|
|
|
|
name = "netmask";
|
|
|
|
value = if addr.prefixLength == 24 then
|
|
|
|
"255.255.255.0"
|
|
|
|
else
|
|
|
|
throw "missing prefix to netmask conversion";
|
|
|
|
}
|
|
|
|
]) ++ lib.optional (interface.ipv4.routes != [ ])
|
|
|
|
(let route = head interface.ipv4.routes;
|
|
|
|
in {
|
|
|
|
name = "gateway";
|
|
|
|
value = route.address;
|
|
|
|
}) ++ lib.optional (interface.useDHCP != null) {
|
|
|
|
name = "dhcp";
|
|
|
|
value = if interface.useDHCP then "true" else "false";
|
|
|
|
};
|
2020-11-12 19:37:16 +01:00
|
|
|
settingsMap = builtins.concatStringsSep ", " (map
|
|
|
|
({ name, value }:
|
|
|
|
''{ mapKey = "${name}", mapValue = "${value}" }'') settings);
|
2020-11-10 16:01:58 +01:00
|
|
|
in pkgs.writeText "${name'}.dhall" ''
|
|
|
|
let Genode = env:DHALL_GENODE
|
|
|
|
|
|
|
|
let Init = Genode.Init
|
|
|
|
|
|
|
|
in Init.Child.flat
|
|
|
|
Init.Child.Attributes::{
|
|
|
|
, binary = "${binary}"
|
|
|
|
, provides = [ "File_system" ]
|
2020-11-12 19:37:16 +01:00
|
|
|
, resources = Init.Resources::{
|
|
|
|
, caps = 128
|
|
|
|
, ram = Genode.units.MiB ${toString ram}
|
|
|
|
}
|
2020-11-10 16:01:58 +01:00
|
|
|
, config = Init.Config::{
|
|
|
|
, policies =
|
|
|
|
[ Init.Config.Policy::{
|
|
|
|
, service = "File_system"
|
2020-11-12 19:37:16 +01:00
|
|
|
, label = Init.LabelSelector.suffix "${name'}"
|
|
|
|
, attributes = toMap { root = "/", writeable="yes" }
|
2020-11-10 16:01:58 +01:00
|
|
|
}
|
|
|
|
]
|
|
|
|
, content =
|
2020-11-12 19:37:16 +01:00
|
|
|
let VFS = Genode.VFS
|
|
|
|
|
|
|
|
in [ VFS.vfs
|
|
|
|
[ VFS.leafAttrs
|
|
|
|
"${interface.genode.stack}"
|
|
|
|
([ ${settingsMap} ] : Genode.Prelude.Map.Type Text Text)
|
|
|
|
]
|
2020-11-10 16:01:58 +01:00
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
}) config.networking.interfaces;
|
|
|
|
|
2020-12-03 12:48:07 +01:00
|
|
|
in lib.filterAttrs (n: v: v != null) (nics // sockets);
|
|
|
|
|
2020-12-10 19:27:53 +01:00
|
|
|
genode.core.children.acpi_drv = {
|
|
|
|
inputs = [ pkgs.genodePackages.acpi_drv ];
|
|
|
|
configFile = pkgs.writeText "acpi_drv.dhall" ''
|
|
|
|
let Genode = env:DHALL_GENODE
|
2020-11-01 20:21:27 +01:00
|
|
|
|
2020-12-10 19:27:53 +01:00
|
|
|
let Init = Genode.Init
|
2020-11-01 20:21:27 +01:00
|
|
|
|
2020-12-10 19:27:53 +01:00
|
|
|
let label = λ(_ : Text) → { local = _, route = _ }
|
2020-11-10 16:01:58 +01:00
|
|
|
|
2020-12-10 19:27:53 +01:00
|
|
|
in Init.Child.flat
|
|
|
|
Init.Child.Attributes::{
|
|
|
|
, binary = "acpi_drv"
|
|
|
|
, resources = Init.Resources::{
|
|
|
|
, caps = 400
|
|
|
|
, ram = Genode.units.MiB 4
|
|
|
|
, constrainPhys = True
|
2020-11-01 20:21:27 +01:00
|
|
|
}
|
2020-12-10 19:27:53 +01:00
|
|
|
, romReports = [ label "acpi", label "smbios_table" ]
|
|
|
|
, routes =
|
|
|
|
[ Init.ServiceRoute.parent "IRQ"
|
|
|
|
, Init.ServiceRoute.parent "IO_MEM"
|
|
|
|
, Init.ServiceRoute.parent "IO_PORT"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
2020-11-10 16:01:58 +01:00
|
|
|
|
2020-12-10 19:27:53 +01:00
|
|
|
genode.core.children.platform_drv = {
|
|
|
|
inputs = [ pkgs.genodePackages.platform_drv ];
|
|
|
|
configFile = let
|
|
|
|
policies =
|
|
|
|
map (policy: ", ${policy}") config.hardware.genode.platform.policies;
|
|
|
|
in pkgs.writeText "platform_drv.dhall" ''
|
|
|
|
let Genode = env:DHALL_GENODE
|
2020-11-10 16:01:58 +01:00
|
|
|
|
2020-12-10 19:27:53 +01:00
|
|
|
let Init = Genode.Init
|
2020-11-10 16:01:58 +01:00
|
|
|
|
2020-12-10 19:27:53 +01:00
|
|
|
in Init.Child.flat
|
|
|
|
Init.Child.Attributes::{
|
|
|
|
, binary = "platform_drv"
|
|
|
|
, resources = Init.Resources::{
|
|
|
|
, caps = 800
|
|
|
|
, ram = Genode.units.MiB 4
|
|
|
|
, constrainPhys = True
|
2020-11-10 16:01:58 +01:00
|
|
|
}
|
2020-12-10 19:27:53 +01:00
|
|
|
, reportRoms = let label = "acpi" in [ { local = label, route = label } ]
|
|
|
|
, routes =
|
|
|
|
[ Init.ServiceRoute.parent "IRQ"
|
|
|
|
, Init.ServiceRoute.parent "IO_MEM"
|
|
|
|
, Init.ServiceRoute.parent "IO_PORT"
|
|
|
|
]
|
|
|
|
, config = Init.Config::{
|
|
|
|
, policies = [ ${toString policies} ]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
genode.core.children.usb_drv = mkIf config.hardware.genode.usb.enable {
|
|
|
|
inputs = [ pkgs.genodePackages.usb_drv ];
|
|
|
|
configFile = builtins.toFile "usb_drv.dhall" ''
|
|
|
|
let Genode = env:DHALL_GENODE
|
|
|
|
|
|
|
|
let XML = Genode.Prelude.XML
|
|
|
|
|
|
|
|
let Init = Genode.Init
|
|
|
|
|
|
|
|
let storageEnable = ${
|
|
|
|
if config.hardware.genode.usb.storage.enable then "True" else "False"
|
|
|
|
}
|
|
|
|
|
|
|
|
in Init.Child.flat
|
|
|
|
Init.Child.Attributes::{
|
|
|
|
, binary = "usb_drv"
|
|
|
|
, resources = Init.Resources::{ caps = 256, ram = Genode.units.MiB 12 }
|
|
|
|
, routes = [ Init.ServiceRoute.parent "IO_MEM" ]
|
|
|
|
, config = Init.Config::{
|
|
|
|
, attributes = toMap { uhci = "yes", ehci = "yes", xhci = "yes" }
|
|
|
|
, content =
|
|
|
|
if storageEnable
|
|
|
|
then [ XML.leaf
|
|
|
|
{ name = "storage", attributes = XML.emptyAttributes }
|
|
|
|
]
|
|
|
|
else [] : List XML.Type
|
|
|
|
, policies =
|
|
|
|
if storageEnable
|
|
|
|
then [ Init.Config.Policy::{
|
|
|
|
, service = "Block"
|
|
|
|
, label = Init.LabelSelector.prefix "part_block"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
else [] : List Init.Config.Policy.Type
|
|
|
|
}
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
2020-11-10 16:01:58 +01:00
|
|
|
|
2020-12-10 19:27:53 +01:00
|
|
|
genode.core.children.fb_drv =
|
|
|
|
mkIf config.hardware.genode.framebuffer.enable {
|
|
|
|
inputs = with pkgs.genodePackages;
|
|
|
|
{
|
|
|
|
"boot" = [ boot_fb_drv ];
|
|
|
|
"vesa" = [ vesa_drv ];
|
|
|
|
}.${config.hardware.genode.framebuffer.driver};
|
|
|
|
configFile = let
|
|
|
|
binary = with pkgs.genodePackages;
|
|
|
|
{
|
|
|
|
"boot" = "boot_fb_drv";
|
|
|
|
"vesa" = "vesa_fb_drv";
|
|
|
|
}.${config.hardware.genode.framebuffer.driver};
|
|
|
|
in builtins.toFile "fb_drv.dhall" ''
|
2020-12-03 12:48:07 +01:00
|
|
|
let Genode = env:DHALL_GENODE
|
|
|
|
|
|
|
|
let XML = Genode.Prelude.XML
|
|
|
|
|
|
|
|
let Init = Genode.Init
|
|
|
|
|
|
|
|
in Init.Child.flat
|
|
|
|
Init.Child.Attributes::{
|
2020-12-10 19:27:53 +01:00
|
|
|
, binary = "${binary}"
|
|
|
|
, resources = Init.Resources::{ caps = 256, ram = Genode.units.MiB 32 }
|
|
|
|
, routes =
|
|
|
|
[ Init.ServiceRoute.parent "IO_MEM"
|
|
|
|
, Init.ServiceRoute.parent "IO_PORT"
|
|
|
|
]
|
2020-12-03 12:48:07 +01:00
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
2020-11-01 20:21:27 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|