diff --git a/repos/gems/run/sculpt.run b/repos/gems/run/sculpt.run index 801acb51d7..4b8ffc3355 100644 --- a/repos/gems/run/sculpt.run +++ b/repos/gems/run/sculpt.run @@ -615,6 +615,8 @@ install_config { + + diff --git a/repos/gems/sculpt/drivers/pc b/repos/gems/sculpt/drivers/pc index 41047a8642..32f52791bb 100644 --- a/repos/gems/sculpt/drivers/pc +++ b/repos/gems/sculpt/drivers/pc @@ -55,7 +55,6 @@ - @@ -90,7 +89,7 @@ - + @@ -137,11 +136,11 @@ - - - - - + + + + + @@ -268,7 +267,6 @@ - diff --git a/repos/gems/src/app/driver_manager/main.cc b/repos/gems/src/app/driver_manager/main.cc index f326405ffc..2989779fc9 100644 --- a/repos/gems/src/app/driver_manager/main.cc +++ b/repos/gems/src/app/driver_manager/main.cc @@ -31,10 +31,6 @@ namespace Driver_manager { using namespace Genode; struct Main; struct Device_driver; - struct Intel_gpu_driver; - struct Intel_fb_driver; - struct Vesa_fb_driver; - struct Boot_fb_driver; struct Ahci_driver; struct Nvme_driver; @@ -119,124 +115,6 @@ class Driver_manager::Device_driver : Noncopyable }; -struct Driver_manager::Intel_gpu_driver : Device_driver -{ - Version version { 0 }; - - void generate_start_node(Xml_generator &xml) const override - { - _gen_forwarded_service(xml, "intel_gpu_drv"); - - xml.node("start", [&] () { - _gen_common_start_node_content(xml, "intel_gpu_drv", "intel_gpu_drv", - Ram_quota{64*1024*1024}, Cap_quota{1400}, - Priority{0}, version); - xml.node("provides", [&] () { - xml.node("service", [&] () { - xml.attribute("name", Gpu::Session::service_name()); }); - xml.node("service", [&] () { - xml.attribute("name", Platform::Session::service_name()); }); - }); - xml.node("route", [&] () { - _gen_config_route(xml, "gpu_drv.config"); - _gen_default_parent_route(xml); - }); - }); - } -}; - - -struct Driver_manager::Intel_fb_driver : Device_driver -{ - Intel_gpu_driver intel_gpu_driver { }; - - Version version { 0 }; - - void generate_start_node(Xml_generator &xml) const override - { - intel_gpu_driver.generate_start_node(xml); - - xml.node("start", [&] () { - _gen_common_start_node_content(xml, "intel_fb_drv", "pc_intel_fb_drv", - Ram_quota{42*1024*1024}, Cap_quota{800}, - Priority{0}, version); - xml.node("heartbeat", [&] () { }); - xml.node("route", [&] () { - _gen_config_route(xml, "fb_drv.config"); - xml.node("service", [&] () { - xml.attribute("name", Platform::Session::service_name()); - xml.node("child", [&] () { - xml.attribute("name", "intel_gpu_drv"); - }); - }); - _gen_default_parent_route(xml); - }); - }); - } -}; - - -struct Driver_manager::Vesa_fb_driver : Device_driver -{ - void generate_start_node(Xml_generator &xml) const override - { - xml.node("start", [&] () { - _gen_common_start_node_content(xml, "vesa_fb_drv", "vesa_fb_drv", - Ram_quota{8*1024*1024}, Cap_quota{110}, - Priority{-1}, Version{0}); - xml.node("route", [&] () { - _gen_config_route(xml, "fb_drv.config"); - _gen_default_parent_route(xml); - }); - }); - } -}; - - -struct Driver_manager::Boot_fb_driver : Device_driver -{ - Ram_quota const _ram_quota; - - struct Mode - { - enum { TYPE_RGB_COLOR = 1 }; - - unsigned _pitch = 0, _height = 0; - - Mode() { } - - Mode(Xml_node node) - : - _pitch(node.attribute_value("pitch", 0U)), - _height(node.attribute_value("height", 0U)) - { - /* check for unsupported type */ - if (node.attribute_value("type", 0U) != TYPE_RGB_COLOR) - _pitch = _height = 0; - } - - size_t num_bytes() const { return _pitch * _height + 1024*1024; } - - bool valid() const { return _pitch * _height != 0; } - }; - - Boot_fb_driver(Mode const mode) : _ram_quota(Ram_quota{mode.num_bytes()}) { } - - void generate_start_node(Xml_generator &xml) const override - { - xml.node("start", [&] () { - _gen_common_start_node_content(xml, "boot_fb_drv", "boot_fb_drv", - _ram_quota, Cap_quota{100}, - Priority{-1}, Version{0}); - xml.node("route", [&] () { - _gen_config_route(xml, "fb_drv.config"); - _gen_default_parent_route(xml); - }); - }); - } -}; - - struct Driver_manager::Ahci_driver : Device_driver { void generate_start_node(Xml_generator &xml) const override @@ -348,37 +226,22 @@ struct Driver_manager::Main { Env &_env; - Attached_rom_dataspace _platform { _env, "platform_info" }; - Attached_rom_dataspace _usb_devices { _env, "usb_devices" }; - Attached_rom_dataspace _usb_policy { _env, "usb_policy" }; - Attached_rom_dataspace _devices { _env, "devices" }; - Attached_rom_dataspace _ahci_ports { _env, "ahci_ports" }; - Attached_rom_dataspace _nvme_ns { _env, "nvme_ns" }; - Attached_rom_dataspace _dynamic_state { _env, "dynamic_state" }; + Attached_rom_dataspace _platform { _env, "platform_info" }; + Attached_rom_dataspace _usb_devices { _env, "usb_devices" }; + Attached_rom_dataspace _usb_policy { _env, "usb_policy" }; + Attached_rom_dataspace _devices { _env, "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" }; Reporter _block_devices { _env, "block_devices" }; - Constructible _intel_fb_driver { }; - Constructible _vesa_fb_driver { }; - Constructible _boot_fb_driver { }; - Constructible _ahci_driver { }; - Constructible _nvme_driver { }; + Constructible _ahci_driver { }; + Constructible _nvme_driver { }; bool _devices_rom_parsed { false }; - bool _use_ohci { true }; - - Boot_fb_driver::Mode _boot_fb_mode() const - { - try { - Xml_node fb = _platform.xml().sub_node("boot").sub_node("framebuffer"); - return Boot_fb_driver::Mode(fb); - } catch (...) { } - return Boot_fb_driver::Mode(); - } - void _handle_devices_update(); Signal_handler
_devices_update_handler { @@ -402,11 +265,6 @@ struct Driver_manager::Main Signal_handler
_nvme_ns_update_handler { _env.ep(), *this, &Main::_handle_nvme_ns_update }; - Signal_handler
_dynamic_state_handler { - _env.ep(), *this, &Main::_handle_dynamic_state }; - - void _handle_dynamic_state(); - static void _gen_parent_service_xml(Xml_generator &xml, char const *name) { xml.node("service", [&] () { xml.attribute("name", name); }); @@ -439,11 +297,10 @@ struct Driver_manager::Main _usb_drv_config.enabled(true); _block_devices.enabled(true); - _devices .sigh(_devices_update_handler); - _usb_policy .sigh(_usb_policy_update_handler); - _ahci_ports .sigh(_ahci_ports_update_handler); - _nvme_ns .sigh(_nvme_ns_update_handler); - _dynamic_state.sigh(_dynamic_state_handler); + _devices .sigh(_devices_update_handler); + _usb_policy.sigh(_usb_policy_update_handler); + _ahci_ports.sigh(_ahci_ports_update_handler); + _nvme_ns .sigh(_nvme_ns_update_handler); _generate_init_config(_init_config); @@ -458,16 +315,11 @@ void Driver_manager::Main::_handle_devices_update() { _devices.update(); - /* decide about fb not before the first valid pci report is available */ if (!_devices.valid()) return; - 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(); + bool has_ahci = false; + bool has_nvme = false; _devices.xml().for_each_sub_node([&] (Xml_node device) { device.with_optional_sub_node("pci-config", [&] (Xml_node pci) { @@ -476,52 +328,19 @@ void Driver_manager::Main::_handle_devices_update() uint16_t const class_code = (uint16_t)(pci.attribute_value("class", 0U) >> 8); enum { - VENDOR_VBOX = 0x80EEU, VENDOR_INTEL = 0x8086U, - CLASS_VGA = 0x300U, CLASS_AHCI = 0x106U, CLASS_NVME = 0x108U, }; - if (class_code == CLASS_VGA) - has_vga = true; - - if (vendor_id == VENDOR_INTEL && class_code == CLASS_VGA) - has_intel_graphics = true; - if (vendor_id == VENDOR_INTEL && class_code == CLASS_AHCI) has_ahci = true; - if (vendor_id == VENDOR_VBOX) - _use_ohci = false; - if (class_code == CLASS_NVME) has_nvme = true; }); }); - if (!_intel_fb_driver.constructed() && has_intel_graphics) { - _intel_fb_driver.construct(); - _vesa_fb_driver.destruct(); - _boot_fb_driver.destruct(); - _generate_init_config(_init_config); - } - - if (!_boot_fb_driver.constructed() && boot_fb_mode.valid() && !has_intel_graphics) { - _intel_fb_driver.destruct(); - _vesa_fb_driver.destruct(); - _boot_fb_driver.construct(boot_fb_mode); - _generate_init_config(_init_config); - } - - if (!_vesa_fb_driver.constructed() && has_vga && !has_intel_graphics && - !boot_fb_mode.valid()) { - _intel_fb_driver.destruct(); - _boot_fb_driver.destruct(); - _vesa_fb_driver.construct(); - _generate_init_config(_init_config); - } - if (!_ahci_driver.constructed() && has_ahci) { _ahci_driver.construct(); _generate_init_config(_init_config); @@ -603,16 +422,6 @@ void Driver_manager::Main::_generate_init_config(Reporter &init_config) const _gen_parent_service_xml(xml, Capture::Session::service_name()); }); - - if (_intel_fb_driver.constructed()) - _intel_fb_driver->generate_start_node(xml); - - if (_vesa_fb_driver.constructed()) - _vesa_fb_driver->generate_start_node(xml); - - if (_boot_fb_driver.constructed()) - _boot_fb_driver->generate_start_node(xml); - if (_ahci_driver.constructed()) _ahci_driver->generate_start_node(xml); @@ -776,36 +585,4 @@ void Driver_manager::Main::_generate_usb_drv_config(Reporter &usb_drv_config, } -void Driver_manager::Main::_handle_dynamic_state() -{ - _dynamic_state.update(); - - bool reconfigure_dynamic_init = false; - - _dynamic_state.xml().for_each_sub_node([&] (Xml_node child) { - - using Name = Device_driver::Name; - - Name const name = child.attribute_value("name", Name()); - - if (name == "intel_fb_drv") { - - unsigned long const skipped_heartbeats = - child.attribute_value("skipped_heartbeats", 0U); - - if (skipped_heartbeats >= 2) { - - if (_intel_fb_driver.constructed()) { - _intel_fb_driver->version.value++; - reconfigure_dynamic_init = true; - } - } - } - }); - - if (reconfigure_dynamic_init) - _generate_init_config(_init_config); -} - - void Component::construct(Genode::Env &env) { static Driver_manager::Main main(env); } diff --git a/repos/gems/src/app/phone_manager/main.cc b/repos/gems/src/app/phone_manager/main.cc index 40e89726bd..f7c73191a0 100644 --- a/repos/gems/src/app/phone_manager/main.cc +++ b/repos/gems/src/app/phone_manager/main.cc @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -113,6 +114,35 @@ struct Sculpt::Main : Input_event_handler, handle_input_event(ev); }); } + + /*********************** + ** Device management ** + ***********************/ + + Attached_rom_dataspace const _platform { _env, "platform_info" }; + + Attached_rom_dataspace _devices { _env, "report -> drivers/devices" }; + + Signal_handler
_devices_handler { + _env.ep(), *this, &Main::_handle_devices }; + + Board_info _board_info { }; + + void _handle_devices() + { + _devices.update(); + + _board_info = Board_info::from_xml(_devices.xml(), _platform.xml()); + + /* enable non-PCI wifi (PinePhone) */ + if (_devices.xml().num_sub_nodes() == 0) + _board_info.wifi_present = true; + + _fb_driver.update(_child_states, _board_info, _platform.xml()); + + update_network_dialog(); + } + Managed_config
_system_config { _env, "system", "system", *this, &Main::_handle_system_config }; @@ -208,6 +238,8 @@ struct Sculpt::Main : Input_event_handler, _update_managed_system_config(); } + Fb_driver _fb_driver { }; + Signal_handler
_gui_mode_handler { _env.ep(), *this, &Main::_handle_gui_mode }; @@ -292,10 +324,6 @@ struct Sculpt::Main : Input_event_handler, */ void refresh_storage_dialog() override { _generate_dialog(); } - Board_info _board_info { .wifi_present = true, - .lan_present = false, - .modem_present = true }; - Network _network { _env, _heap, *this, *this, _child_states, *this, _runtime_state }; /** @@ -997,8 +1025,6 @@ struct Sculpt::Main : Input_event_handler, void _handle_runtime_state(); - Attached_rom_dataspace const _platform { _env, "platform_info" }; - /******************** ** Touch keyboard ** @@ -1932,6 +1958,7 @@ struct Sculpt::Main : Input_event_handler, * Subscribe to reports */ _update_state_rom .sigh(_update_state_handler); + _devices .sigh(_devices_handler); _window_list .sigh(_window_list_handler); _decorator_margins .sigh(_decorator_margins_handler); _scan_rom .sigh(_scan_handler); @@ -1949,6 +1976,7 @@ struct Sculpt::Main : Input_event_handler, _handle_leitzentrale(); _handle_gui_mode(); _storage.handle_storage_devices_update(); + _handle_devices(); _handle_runtime_config(); _handle_modem_state(); @@ -2357,6 +2385,8 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const xml.attribute("height", _affinity_space.height()); }); + _fb_driver.gen_start_nodes(xml); + _dialog_runtime.gen_start_nodes(xml); _touch_keyboard.gen_start_node(xml); diff --git a/repos/gems/src/app/sculpt_manager/fb_driver.h b/repos/gems/src/app/sculpt_manager/fb_driver.h new file mode 100644 index 0000000000..6af1a7dbb8 --- /dev/null +++ b/repos/gems/src/app/sculpt_manager/fb_driver.h @@ -0,0 +1,128 @@ +/* + * \brief Sculpt framebuffer-driver management + * \author Norman Feske + * \date 2024-03-15 + */ + +/* + * Copyright (C) 2024 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _FB_DRIVER_H_ +#define _FB_DRIVER_H_ + +/* local includes */ +#include +#include +#include + +namespace Sculpt { struct Fb_driver; } + + +struct Sculpt::Fb_driver : private Noncopyable +{ + Constructible _intel_gpu { }, + _intel_fb { }, + _vesa_fb { }, + _boot_fb { }; + + void gen_start_nodes(Xml_generator &xml) const + { + auto gen_common_routes = [&] (Xml_generator &xml) + { + gen_parent_route (xml); + gen_parent_route (xml); + gen_parent_route (xml); + gen_parent_route (xml); + gen_parent_route (xml); + gen_parent_route (xml); + }; + + auto gen_capture_route = [&] (Xml_generator &xml) + { + gen_service_node(xml, [&] { + xml.node("parent", [&] { + xml.attribute("label", "global"); }); }); + }; + + auto start_node = [&] (auto const &driver, auto const &binary, auto const &fn) + { + if (driver.constructed()) + xml.node("start", [&] { + driver->gen_start_node_content(xml); + gen_named_node(xml, "binary", binary); + fn(); }); + }; + + start_node(_intel_gpu, "intel_gpu_drv", [&] { + xml.node("provides", [&] { + gen_service_node (xml, [&] () { }); + gen_service_node(xml, [&] () { }); + }); + xml.node("route", [&] { + gen_parent_route(xml); + gen_parent_rom_route(xml, "config", "config -> gpu_drv"); + gen_parent_route(xml); + gen_common_routes(xml); + }); + }); + + start_node(_intel_fb, "pc_intel_fb_drv", [&] { + xml.node("route", [&] { + gen_service_node(xml, [&] { + gen_named_node(xml, "child", "intel_gpu"); }); + gen_capture_route(xml); + gen_parent_rom_route(xml, "config", "config -> fb_drv"); + gen_parent_rom_route(xml, "intel_opregion", "report -> drivers/intel_opregion"); + gen_parent_route(xml); + gen_common_routes(xml); + }); + }); + + start_node(_vesa_fb, "vesa_fb_drv", [&] { + xml.node("route", [&] () { + gen_parent_route(xml); + gen_capture_route(xml); + gen_parent_rom_route(xml, "config", "config -> fb_drv"); + gen_parent_route(xml); + gen_parent_route(xml); + gen_common_routes(xml); + }); + }); + + start_node(_boot_fb, "boot_fb_drv", [&] { + xml.node("route", [&] () { + gen_parent_rom_route(xml, "config", "config -> fb_drv"); + gen_parent_route(xml); + gen_capture_route(xml); + gen_common_routes(xml); + }); + }); + }; + + void update(Registry ®istry, Board_info const &board_info, + Xml_node const &platform) + { + _intel_gpu.conditional(board_info.intel_gfx_present, + registry, "intel_gpu", Priority::MULTIMEDIA, + Ram_quota { 32*1024*1024 }, Cap_quota { 1400 }); + + _intel_fb.conditional(board_info.intel_gfx_present, + registry, "intel_fb", Priority::MULTIMEDIA, + Ram_quota { 16*1024*1024 }, Cap_quota { 800 }); + + _vesa_fb.conditional(board_info.vesa_fb_present, + registry, "vesa_fb", Priority::MULTIMEDIA, + Ram_quota { 8*1024*1024 }, Cap_quota { 110 }); + + if (board_info.boot_fb_present && !_boot_fb.constructed()) + Boot_fb::with_mode(platform, [&] (Boot_fb::Mode mode) { + _boot_fb.construct(registry, "boot_fb", Priority::MULTIMEDIA, + mode.ram_quota(), Cap_quota { 100 }); }); + } +}; + +#endif /* _FB_DRIVER_H_ */ diff --git a/repos/gems/src/app/sculpt_manager/main.cc b/repos/gems/src/app/sculpt_manager/main.cc index a364675749..233645e363 100644 --- a/repos/gems/src/app/sculpt_manager/main.cc +++ b/repos/gems/src/app/sculpt_manager/main.cc @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -203,6 +204,8 @@ struct Sculpt::Main : Input_event_handler, ** Device discovery ** **********************/ + Attached_rom_dataspace const _platform { _env, "platform_info" }; + Attached_rom_dataspace _devices { _env, "report -> drivers/devices" }; Signal_handler
_devices_handler { @@ -210,11 +213,15 @@ struct Sculpt::Main : Input_event_handler, Board_info _board_info { }; + Fb_driver _fb_driver { }; + void _handle_devices() { _devices.update(); - _board_info = Board_info::from_xml(_devices.xml()); + _board_info = Board_info::from_xml(_devices.xml(), _platform.xml()); + + _fb_driver.update(_child_states, _board_info, _platform.xml()); update_network_dialog(); } @@ -662,8 +669,6 @@ struct Sculpt::Main : Input_event_handler, void _handle_runtime_state(); - Attached_rom_dataspace const _platform { _env, "platform_info" }; - /**************************************** ** Cached model of the runtime config ** @@ -2042,6 +2047,8 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const xml.attribute("height", _affinity_space.height()); }); + _fb_driver.gen_start_nodes(xml); + _dialog_runtime.gen_start_nodes(xml); _storage.gen_runtime_start_nodes(xml); diff --git a/repos/gems/src/app/sculpt_manager/model/board_info.h b/repos/gems/src/app/sculpt_manager/model/board_info.h index 267919c2aa..fc9e788743 100644 --- a/repos/gems/src/app/sculpt_manager/model/board_info.h +++ b/repos/gems/src/app/sculpt_manager/model/board_info.h @@ -14,7 +14,7 @@ #ifndef _MODEL__BOARD_INFO_H_ #define _MODEL__BOARD_INFO_H_ -#include "types.h" +#include namespace Sculpt { struct Board_info; } @@ -23,33 +23,78 @@ struct Sculpt::Board_info bool wifi_present; bool lan_present; bool modem_present; + bool intel_gfx_present; + bool boot_fb_present; + bool vesa_fb_present; + bool nvme_present; + bool ahci_present; - static Board_info from_xml(Xml_node const &devices) + static Board_info from_xml(Xml_node const &devices, Xml_node const &platform) { - bool wifi = false, lan = false; + Board_info result { }; + + Boot_fb::with_mode(platform, [&] (Boot_fb::Mode mode) { + result.boot_fb_present = mode.valid(); }); + + bool vga = false; devices.for_each_sub_node("device", [&] (Xml_node const &device) { device.with_optional_sub_node("pci-config", [&] (Xml_node const &pci) { - auto has_class = [&] (unsigned class_value) - { - return pci.attribute_value("class", 0UL) == class_value; + enum class Pci_class : unsigned { + WIFI = 0x28000, + LAN = 0x20000, + VGA = 0x30000, + AHCI = 0x10600, + NVME = 0x10800, }; - /* PCI class values */ - static constexpr unsigned WIFI = 0x28000, - LAN = 0x20000; + enum class Pci_vendor : unsigned { INTEL = 0x8086U, }; - if (has_class(WIFI)) wifi = true; - if (has_class(LAN)) lan = true; + auto matches_class = [&] (Pci_class value) + { + return pci.attribute_value("class", 0U) == unsigned(value); + }; + + auto matches_vendor = [&] (Pci_vendor value) + { + return pci.attribute_value("vendor_id", 0U) == unsigned(value); + }; + + if (matches_class(Pci_class::WIFI)) result.wifi_present = true; + if (matches_class(Pci_class::LAN)) result.lan_present = true; + if (matches_class(Pci_class::NVME)) result.nvme_present = true; + + if (matches_class(Pci_class::AHCI) && matches_vendor(Pci_vendor::INTEL)) + result.ahci_present = true; + + if (matches_class(Pci_class::VGA)) { + vga = true; + if (matches_vendor(Pci_vendor::INTEL)) + result.intel_gfx_present = true; + } }); }); - return { - .wifi_present = wifi, - .lan_present = lan, - .modem_present = false - }; + if (result.intel_gfx_present) + result.boot_fb_present = false; + + if (vga && !result.intel_gfx_present && !result.boot_fb_present) + result.vesa_fb_present = true; + + return result; + } + + void print(Output &out) const + { + Genode::print(out, "wifi=", wifi_present, + " lan=", lan_present, + " modem=", modem_present, + " intel_gfx=", intel_gfx_present, + " boot_fb=", boot_fb_present, + " vesa_fb=", vesa_fb_present, + " nvme=", nvme_present, + " ahci=", ahci_present); } }; diff --git a/repos/gems/src/app/sculpt_manager/model/boot_fb.h b/repos/gems/src/app/sculpt_manager/model/boot_fb.h new file mode 100644 index 0000000000..3e3bfc4398 --- /dev/null +++ b/repos/gems/src/app/sculpt_manager/model/boot_fb.h @@ -0,0 +1,54 @@ +/* + * \brief Boot-time framebuffer information + * \author Norman Feske + * \date 2024-03-15 + */ + +/* + * Copyright (C) 2024 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _MODEL__BOOT_FB_H_ +#define _MODEL__BOOT_FB_H_ + +#include + +namespace Sculpt { struct Boot_fb; } + + +struct Sculpt::Boot_fb +{ + struct Mode + { + unsigned pitch, height; + + static Mode from_xml(Xml_node const &framebuffer) + { + static constexpr unsigned TYPE_RGB_COLOR = 1; + + if (framebuffer.attribute_value("type", 0U) != TYPE_RGB_COLOR) + return { }; + + return { + .pitch = framebuffer.attribute_value("pitch", 0U), + .height = framebuffer.attribute_value("height", 0U) + }; + } + + Ram_quota ram_quota() const { return { pitch*height + 1024*1024 }; } + + bool valid() const { return pitch*height != 0; } + }; + + static void with_mode(Xml_node const &platform, auto const &fn) + { + platform.with_optional_sub_node("boot", [&] (Xml_node const &boot) { + boot.with_optional_sub_node("framebuffer", [&] (Xml_node const &framebuffer) { + fn(Mode::from_xml(framebuffer)); }); }); + } +}; + +#endif /* _MODEL__BOOT_FB_H_ */ diff --git a/repos/gems/src/app/sculpt_manager/types.h b/repos/gems/src/app/sculpt_manager/types.h index e37fd5fb73..088105f53d 100644 --- a/repos/gems/src/app/sculpt_manager/types.h +++ b/repos/gems/src/app/sculpt_manager/types.h @@ -32,6 +32,8 @@ #include #include #include +#include +#include namespace Sculpt {