diff --git a/repos/gems/recipes/raw/drivers_managed-pc/drivers.config b/repos/gems/recipes/raw/drivers_managed-pc/drivers.config
index c149638224..f3ff7edbac 100644
--- a/repos/gems/recipes/raw/drivers_managed-pc/drivers.config
+++ b/repos/gems/recipes/raw/drivers_managed-pc/drivers.config
@@ -44,6 +44,7 @@
+
@@ -108,6 +109,7 @@
+
@@ -194,6 +196,7 @@
+
@@ -211,6 +214,7 @@
+
diff --git a/repos/gems/src/app/driver_manager/main.cc b/repos/gems/src/app/driver_manager/main.cc
index 75dba11c30..f75d229e4c 100644
--- a/repos/gems/src/app/driver_manager/main.cc
+++ b/repos/gems/src/app/driver_manager/main.cc
@@ -35,6 +35,7 @@ namespace Driver_manager {
struct Vesa_fb_driver;
struct Boot_fb_driver;
struct Ahci_driver;
+ struct Nvme_driver;
struct Priority { int value; };
}
@@ -258,6 +259,57 @@ struct Driver_manager::Ahci_driver : Device_driver
};
+struct Driver_manager::Nvme_driver : Device_driver
+{
+ void generate_start_node(Xml_generator &xml) const override
+ {
+ xml.node("start", [&] () {
+ _gen_common_start_node_content(xml, "nvme_drv", "nvme_drv",
+ Ram_quota{8*1024*1024}, Cap_quota{100},
+ Priority{-1});
+ _gen_provides_node(xml);
+ xml.node("config", [&] () {
+ xml.node("report", [&] () { xml.attribute("namespaces", "yes"); });
+ xml.node("policy", [&] () {
+ xml.attribute("label_suffix", String<64>("nvme-0"));
+ xml.attribute("namespace", 1);
+ xml.attribute("writeable", "yes");
+ });
+ });
+ xml.node("route", [&] () {
+ xml.node("service", [&] () {
+ xml.attribute("name", "Report");
+ xml.node("parent", [&] () { xml.attribute("label", "nvme_ns"); });
+ });
+ _gen_default_parent_route(xml);
+ });
+ });
+ }
+
+ typedef String<32> Default_label;
+
+ void gen_service_forwarding_policy(Xml_generator &xml,
+ Default_label const &default_label) const
+ {
+ xml.node("policy", [&] () {
+ xml.attribute("label_suffix", String<64>("nvme-0"));
+ xml.node("child", [&] () {
+ xml.attribute("name", "nvme_drv"); });
+ });
+
+ if (default_label.valid()) {
+ xml.node("policy", [&] () {
+ xml.attribute("label_suffix", " default");
+ xml.node("child", [&] () {
+ xml.attribute("name", "nvme_drv");
+ xml.attribute("label", default_label);
+ });
+ });
+ }
+ }
+};
+
+
struct Driver_manager::Main : Block_devices_generator
{
Env &_env;
@@ -266,6 +318,7 @@ struct Driver_manager::Main : Block_devices_generator
Attached_rom_dataspace _usb_devices { _env, "usb_devices" };
Attached_rom_dataspace _pci_devices { _env, "pci_devices" };
Attached_rom_dataspace _ahci_ports { _env, "ahci_ports" };
+ Attached_rom_dataspace _nvme_ns { _env, "nvme_ns" };
Reporter _init_config { _env, "config", "init.config" };
Reporter _usb_drv_config { _env, "config", "usb_drv.config" };
@@ -275,6 +328,7 @@ struct Driver_manager::Main : Block_devices_generator
Constructible _vesa_fb_driver;
Constructible _boot_fb_driver;
Constructible _ahci_driver;
+ Constructible _nvme_driver;
Boot_fb_driver::Mode _boot_fb_mode() const
{
@@ -300,6 +354,11 @@ struct Driver_manager::Main : Block_devices_generator
Signal_handler _ahci_ports_update_handler {
_env.ep(), *this, &Main::_handle_ahci_ports_update };
+ void _handle_nvme_ns_update();
+
+ Signal_handler _nvme_ns_update_handler {
+ _env.ep(), *this, &Main::_handle_nvme_ns_update };
+
static void _gen_parent_service_xml(Xml_generator &xml, char const *name)
{
xml.node("service", [&] () { xml.attribute("name", name); });
@@ -325,6 +384,7 @@ struct Driver_manager::Main : Block_devices_generator
_pci_devices.sigh(_pci_devices_update_handler);
_usb_devices.sigh(_usb_devices_update_handler);
_ahci_ports .sigh(_ahci_ports_update_handler);
+ _nvme_ns .sigh(_nvme_ns_update_handler);
_generate_init_config(_init_config);
_generate_usb_drv_config(_usb_drv_config, Xml_node(""));
@@ -332,6 +392,7 @@ struct Driver_manager::Main : Block_devices_generator
_handle_pci_devices_update();
_handle_usb_devices_update();
_handle_ahci_ports_update();
+ _handle_nvme_ns_update();
}
};
@@ -347,6 +408,7 @@ void Driver_manager::Main::_handle_pci_devices_update()
bool has_vga = false;
bool has_intel_graphics = false;
bool has_ahci = false;
+ bool has_nvme = false;
Boot_fb_driver::Mode const boot_fb_mode = _boot_fb_mode();
@@ -359,6 +421,7 @@ void Driver_manager::Main::_handle_pci_devices_update()
VENDOR_INTEL = 0x8086U,
CLASS_VGA = 0x300U,
CLASS_AHCI = 0x106U,
+ CLASS_NVME = 0x108U,
};
if (class_code == CLASS_VGA)
@@ -369,6 +432,9 @@ void Driver_manager::Main::_handle_pci_devices_update()
if (vendor_id == VENDOR_INTEL && class_code == CLASS_AHCI)
has_ahci = true;
+
+ if (class_code == CLASS_NVME)
+ has_nvme = true;
});
if (!_intel_fb_driver.constructed() && has_intel_graphics) {
@@ -397,6 +463,11 @@ void Driver_manager::Main::_handle_pci_devices_update()
_ahci_driver.construct();
_generate_init_config(_init_config);
}
+
+ if (!_nvme_driver.constructed() && has_nvme) {
+ _nvme_driver.construct();
+ _generate_init_config(_init_config);
+ }
}
@@ -410,6 +481,16 @@ void Driver_manager::Main::_handle_ahci_ports_update()
}
+void Driver_manager::Main::_handle_nvme_ns_update()
+{
+ _nvme_ns.update();
+ _generate_block_devices(_block_devices);
+
+ /* update service forwarding rules */
+ _generate_init_config(_init_config);
+}
+
+
void Driver_manager::Main::_handle_usb_devices_update()
{
_usb_devices.update();
@@ -454,13 +535,25 @@ void Driver_manager::Main::_generate_init_config(Reporter &init_config) const
if (_ahci_driver.constructed())
_ahci_driver->generate_start_node(xml);
+ if (_nvme_driver.constructed())
+ _nvme_driver->generate_start_node(xml);
+
/* block-service forwarding rules */
- if (_ahci_driver.constructed() && _ahci_ports.xml().has_sub_node("port")) {
- xml.node("service", [&] () {
- xml.attribute("name", Block::Session::service_name());
- _ahci_driver->gen_service_forwarding_policy(xml, _default_block_device());
- });
- }
+ bool const ahci = _ahci_driver.constructed() && _ahci_ports.xml().has_sub_node("port");
+ bool const nvme = _nvme_driver.constructed() && _nvme_ns.xml().has_sub_node("namespace");
+
+ if (!ahci && !nvme) return;
+
+ bool const ahci_and_nvme = ahci && nvme;
+ xml.node("service", [&] () {
+ xml.attribute("name", Block::Session::service_name());
+ if (ahci)
+ _ahci_driver->gen_service_forwarding_policy(xml,
+ ahci_and_nvme ? Ahci_driver::Default_label() : _default_block_device());
+ if (nvme)
+ _nvme_driver->gen_service_forwarding_policy(xml,
+ ahci_and_nvme ? Nvme_driver::Default_label() : "nvme-0");
+ });
});
}
@@ -513,6 +606,30 @@ void Driver_manager::Main::_generate_block_devices(Reporter &block_devices) cons
xml.attribute("model", model);
});
});
+
+ /* for now just report the first name space */
+ if (_nvme_ns.xml().has_sub_node("namespace")) {
+
+ Xml_node nvme_ctrl = _nvme_ns.xml();
+ Xml_node nvme_ns = _nvme_ns.xml().sub_node("namespace");
+ xml.node("device", [&] () {
+
+ unsigned long const
+ block_count = nvme_ns.attribute_value("block_count", 0UL),
+ block_size = nvme_ns.attribute_value("block_size", 0UL);
+
+ typedef String<40+1> Model;
+ Model const model = nvme_ctrl.attribute_value("model", Model());
+ typedef String<20+1> Serial;
+ Serial const serial = nvme_ctrl.attribute_value("serial", Serial());
+
+ xml.attribute("label", String<16>("nvme-0"));
+ xml.attribute("block_count", block_count);
+ xml.attribute("block_size", block_size);
+ xml.attribute("model", model);
+ xml.attribute("serial", serial);
+ });
+ }
});
}