From 69e71147efa8eed76d46f51e796f1cbd4c0caed8 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Tue, 1 Aug 2017 19:05:56 +0200 Subject: [PATCH] platform_drv: replace nova specific device_pd by using generic Pd_session::map instead for eager memory mappings of DMA memory. Issue #2209 --- .../recipes/src/base-nova/content.mk | 10 - repos/base/run/platform_drv.inc | 2 - .../drivers/platform/spec/x86/device_pd.cc | 103 ++++++++ .../src/drivers/platform/spec/x86/device_pd.h | 96 ++++++-- .../platform/spec/x86/device_pd/main.cc | 224 ------------------ .../platform/spec/x86/device_pd/target.mk | 6 - .../platform/spec/x86/pci_device_pd_ipc.h | 85 ------- .../platform/spec/x86/pci_session_component.h | 204 ++-------------- .../src/drivers/platform/spec/x86/target.mk | 1 + 9 files changed, 199 insertions(+), 532 deletions(-) create mode 100644 repos/os/src/drivers/platform/spec/x86/device_pd.cc delete mode 100644 repos/os/src/drivers/platform/spec/x86/device_pd/main.cc delete mode 100644 repos/os/src/drivers/platform/spec/x86/device_pd/target.mk delete mode 100644 repos/os/src/drivers/platform/spec/x86/pci_device_pd_ipc.h diff --git a/repos/base-nova/recipes/src/base-nova/content.mk b/repos/base-nova/recipes/src/base-nova/content.mk index 94a9b2f49d..876ae7e2ad 100644 --- a/repos/base-nova/recipes/src/base-nova/content.mk +++ b/repos/base-nova/recipes/src/base-nova/content.mk @@ -15,16 +15,6 @@ include/spec/%/trace/timestamp.h: cp $(GENODE_DIR)/repos/os/$@ $@ -DEVICE_PD_SRC := src/drivers/platform/spec/x86/pci_device_pd_ipc.h \ - src/drivers/platform/spec/x86/device_pd \ - include/os/static_root.h - -content: $(DEVICE_PD_SRC) -$(DEVICE_PD_SRC): - mkdir -p $(dir $@) - cp -r $(GENODE_DIR)/repos/os/$@ $@ - - content: README README: cp $(REP_DIR)/recipes/src/base-nova/README $@ diff --git a/repos/base/run/platform_drv.inc b/repos/base/run/platform_drv.inc index 6a46a77646..bfb4db8104 100644 --- a/repos/base/run/platform_drv.inc +++ b/repos/base/run/platform_drv.inc @@ -54,7 +54,6 @@ proc platform_drv_build_components {} { lappend_if [have_platform_drv] drv_build_components drivers/platform lappend_if [have_spec acpi] drv_build_components drivers/acpi lappend_if [have_spec acpi] drv_build_components server/report_rom - lappend_if [have_spec nova] drv_build_components drivers/platform/spec/x86/device_pd return $drv_build_components } @@ -69,7 +68,6 @@ proc platform_drv_boot_modules {} { lappend_if [have_platform_drv] drv_boot_modules platform_drv lappend_if [have_spec acpi] drv_boot_modules acpi_drv lappend_if [have_spec acpi] drv_boot_modules report_rom - lappend_if [have_spec nova] drv_boot_modules device_pd lappend_if [have_spec muen] drv_boot_modules acpi return $drv_boot_modules } diff --git a/repos/os/src/drivers/platform/spec/x86/device_pd.cc b/repos/os/src/drivers/platform/spec/x86/device_pd.cc new file mode 100644 index 0000000000..f82240935c --- /dev/null +++ b/repos/os/src/drivers/platform/spec/x86/device_pd.cc @@ -0,0 +1,103 @@ +/* + * \brief Pci device protection domain service for platform driver + * \author Alexander Boettcher + * \date 2013-02-10 + */ + +/* + * Copyright (C) 2013-2017 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. + */ + +#include +#include +#include +#include + +#include + +#include "device_pd.h" + +void Platform::Device_pd::attach_dma_mem(Genode::Dataspace_capability ds_cap) +{ + using namespace Genode; + + Dataspace_client ds_client(ds_cap); + + addr_t const phys = ds_client.phys_addr(); + size_t const size = ds_client.size(); + + addr_t page = ~0UL; + + try { + page = _address_space.attach_at(ds_cap, phys); + /* trigger eager mapping of memory */ + _pd.map(page, size); + } + catch (Out_of_ram) { throw; } + catch (Out_of_caps) { throw; } + catch (Region_map::Region_conflict) { + /* + * DMA memory already attached before. + */ + page = phys; + } catch (...) { + error(_label, ": attach_at or map failed"); + } + + /* sanity check */ + if ((page == ~0UL) || (page != phys)) { + if (page != ~0UL) + _address_space.detach(page); + + Genode::error(_label, ": attachment of DMA memory @ ", + Genode::Hex(phys), "+", Genode::Hex(size), " failed page=", Genode::Hex(page)); + return; + } +} + +void Platform::Device_pd::assign_pci(Genode::Io_mem_dataspace_capability io_mem_cap, + Genode::uint16_t rid) +{ + using namespace Genode; + + Dataspace_client ds_client(io_mem_cap); + addr_t const phys = ds_client.phys_addr(); + + addr_t page = _address_space.attach_at(io_mem_cap, phys); + + /* sanity check */ + if (!page) + throw Region_map::Region_conflict(); + + /* trigger eager mapping of memory */ + _pd.map(page, ds_client.size()); + + /* utility to print rid value */ + struct Rid + { + Genode::uint16_t const v; + explicit Rid(Genode::uint16_t rid) : v(rid) { } + void print(Genode::Output &out) const + { + using Genode::print; + using Genode::Hex; + print(out, Hex(v >> 8, Hex::Prefix::OMIT_PREFIX), ":", + Hex((v >> 3) & 0x1f, Hex::Prefix::OMIT_PREFIX), ".", + Hex(v & 0x7, Hex::Prefix::OMIT_PREFIX)); + } + }; + + /* try to assign pci device to this protection domain */ + if (!_pd.assign_pci(page, rid)) + Genode::error(_label, ": assignment of PCI device ", Rid(rid), " failed ", + "phys=", Genode::Hex(ds_client.phys_addr()), " " + "virt=", Genode::Hex(page)); + else + Genode::log(_label,": assignment of PCI device ", Rid(rid), " succeeded"); + + /* we don't need the mapping anymore */ + _address_space.detach(page); +} diff --git a/repos/os/src/drivers/platform/spec/x86/device_pd.h b/repos/os/src/drivers/platform/spec/x86/device_pd.h index 09deb108b2..6c1575b9f5 100644 --- a/repos/os/src/drivers/platform/spec/x86/device_pd.h +++ b/repos/os/src/drivers/platform/spec/x86/device_pd.h @@ -13,33 +13,87 @@ #pragma once -#include -#include +/* base */ +#include +#include +#include -enum { STACK_SIZE = 4 * sizeof(void *) * 1024 }; +/* os */ +#include -namespace Platform { class Device_pd_policy; } +namespace Platform { class Device_pd; } -class Platform::Device_pd_policy -: - private Genode::Static_parent_services, - public Genode::Slave::Policy +class Platform::Device_pd { + private: + + Genode::Pd_connection _pd; + Genode::Session_label const &_label; + + /** + * Custom handling of PD-session depletion during attach operations + * + * The default implementation of 'env.rm()' automatically issues a resource + * request if the PD session quota gets exhausted. For the device PD, we don't + * want to issue resource requests but let the platform driver reflect this + * condition to its client. + */ + struct Expanding_region_map_client : Genode::Region_map_client + { + Genode::Env &_env; + + Expanding_region_map_client(Genode::Env &env, + Genode::Capability address_space) + : + Region_map_client(address_space), _env(env) + { } + + Local_addr attach(Genode::Dataspace_capability ds, + Genode::size_t size = 0, Genode::off_t offset = 0, + bool use_local_addr = false, + Local_addr local_addr = (void *)0, + bool executable = false) override + { + return Genode::retry( + [&] () { + return Genode::retry( + [&] () { + return Region_map_client::attach(ds, size, offset, + use_local_addr, + local_addr, + executable); }, + [&] () { + enum { UPGRADE_CAP_QUOTA = 2 }; + if (_env.pd().avail_caps().value < UPGRADE_CAP_QUOTA) + throw; + + Genode::String<32> arg("cap_quota=", (unsigned)UPGRADE_CAP_QUOTA); + _env.upgrade(Genode::Parent::Env::pd(), arg.string()); + } + ); + }, + [&] () { + enum { UPGRADE_RAM_QUOTA = 4096 }; + if (_env.ram().avail_ram().value < UPGRADE_RAM_QUOTA) + throw; + + Genode::String<32> arg("ram_quota=", (unsigned)UPGRADE_RAM_QUOTA); + _env.upgrade(Genode::Parent::Env::pd(), arg.string()); + } + ); + } + } _address_space; + public: - Device_pd_policy(Genode::Rpc_entrypoint &slave_ep, - Genode::Region_map &local_rm, - Genode::Pd_session &pd_ref, - Genode::Pd_session_capability pd_ref_cap, - Genode::Cap_quota cap_quota, - Genode::Ram_quota ram_quota, - Genode::Session_label const &label) + Device_pd(Genode::Env &env, + Genode::Session_label const &label) : - Genode::Slave::Policy(label, "device_pd", *this, slave_ep, local_rm, - pd_ref, pd_ref_cap, cap_quota, ram_quota) + _pd(env, label.string()), + _label(label), + _address_space(env, _pd.address_space()) { } -}; + void attach_dma_mem(Genode::Dataspace_capability); + void assign_pci(Genode::Io_mem_dataspace_capability, Genode::uint16_t); +}; diff --git a/repos/os/src/drivers/platform/spec/x86/device_pd/main.cc b/repos/os/src/drivers/platform/spec/x86/device_pd/main.cc deleted file mode 100644 index 486ffcb94e..0000000000 --- a/repos/os/src/drivers/platform/spec/x86/device_pd/main.cc +++ /dev/null @@ -1,224 +0,0 @@ -/* - * \brief Pci device protection domain service for platform driver - * \author Alexander Boettcher - * \date 2013-02-10 - */ - -/* - * Copyright (C) 2013-2017 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. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "../pci_device_pd_ipc.h" - - -/** - * Custom handling of PD-session depletion during attach operations - * - * The default implementation of 'env.rm()' automatically issues a resource - * request if the PD session quota gets exhausted. For the device PD, we don't - * want to issue resource requests but let the platform driver reflect this - * condition to its client. - */ -struct Expanding_region_map_client : Genode::Region_map_client -{ - Genode::Env &_env; - - Expanding_region_map_client(Genode::Env &env) - : - Region_map_client(env.pd().address_space()), _env(env) - { } - - Local_addr attach(Genode::Dataspace_capability ds, - Genode::size_t size, Genode::off_t offset, - bool use_local_addr, - Local_addr local_addr, - bool executable) override - { - return Genode::retry( - [&] () { - return Genode::retry( - [&] () { - return Region_map_client::attach(ds, size, offset, - use_local_addr, - local_addr, - executable); }, - [&] () { - enum { UPGRADE_CAP_QUOTA = 2 }; - if (_env.pd().avail_caps().value < UPGRADE_CAP_QUOTA) - throw; - - Genode::String<32> arg("cap_quota=", (unsigned)UPGRADE_CAP_QUOTA); - _env.upgrade(Genode::Parent::Env::pd(), arg.string()); - } - ); - }, - [&] () { - enum { UPGRADE_RAM_QUOTA = 4096 }; - if (_env.ram().avail_ram().value < UPGRADE_RAM_QUOTA) - throw; - - Genode::String<32> arg("ram_quota=", (unsigned)UPGRADE_RAM_QUOTA); - _env.upgrade(Genode::Parent::Env::pd(), arg.string()); - } - ); - } -}; - - -static bool map_eager(Genode::addr_t const page, unsigned log2_order) -{ - using Genode::addr_t; - - Genode::Thread * myself = Genode::Thread::myself(); - Nova::Utcb * utcb = reinterpret_cast(myself->utcb()); - Nova::Rights const mapping_rw(true, true, false); - - addr_t const page_fault_portal = myself->native_thread().exc_pt_sel + 14; - - while (true) { - /* setup faked page fault information */ - utcb->set_msg_word(((addr_t)&utcb->qual[2] - (addr_t)utcb->msg()) / - sizeof(addr_t)); - utcb->ip = reinterpret_cast(map_eager); - utcb->qual[1] = page; - utcb->crd_rcv = Nova::Mem_crd(page >> 12, log2_order - 12, mapping_rw); - - /* trigger faked page fault */ - Genode::uint8_t res = Nova::call(page_fault_portal); - - bool const retry = utcb->msg_words(); - if (res != Nova::NOVA_OK || !retry) - return res == Nova::NOVA_OK; - }; -} - - -void Platform::Device_pd_component::attach_dma_mem(Genode::Dataspace_capability ds_cap) -{ - using namespace Genode; - - Dataspace_client ds_client(ds_cap); - - addr_t const phys = ds_client.phys_addr(); - size_t const size = ds_client.size(); - - addr_t page = ~0UL; - - try { page = _address_space.attach_at(ds_cap, phys); } - catch (Out_of_ram) { throw; } - catch (Out_of_caps) { throw; } - catch (Region_map::Region_conflict) { - /* - * DMA memory already attached before or collision with normal - * device_pd memory (text, data, etc). - * Currently we can't distinguish it easily - show error - * message as a precaution. - */ - Genode::error("region conflict"); - } catch (...) { } - - /* sanity check */ - if ((page == ~0UL) || (page != phys)) { - if (page != ~0UL) - _address_space.detach(page); - - Genode::error("attachment of DMA memory @ ", - Genode::Hex(phys), "+", Genode::Hex(size), " failed"); - return; - } - - Genode::Flexpage_iterator it(page, size, page, size, 0); - for (Genode::Flexpage flex = it.page(); flex.valid(); flex = it.page()) { - if (map_eager(flex.addr, flex.log2_order)) - continue; - - Genode::error("attachment of DMA memory @ ", - Genode::Hex(phys), "+", Genode::Hex(size), " failed at ", - flex.addr); - return; - } -} - -void Platform::Device_pd_component::assign_pci(Genode::Io_mem_dataspace_capability io_mem_cap, - Genode::uint16_t rid) -{ - using namespace Genode; - - Dataspace_client ds_client(io_mem_cap); - - addr_t page = _address_space.attach(io_mem_cap); - /* sanity check */ - if (!page) - throw Region_map::Region_conflict(); - - /* trigger mapping of whole memory area */ - if (!map_eager(page, 12)) - Genode::error("assignment of PCI device failed - ", Genode::Hex(page)); - - /* utility to print rid value */ - struct Rid - { - Genode::uint16_t const v; - explicit Rid(Genode::uint16_t rid) : v(rid) { } - void print(Genode::Output &out) const - { - using Genode::print; - using Genode::Hex; - print(out, Hex(v >> 8, Hex::Prefix::OMIT_PREFIX), ":", - Hex((v >> 3) & 0x1f, Hex::Prefix::OMIT_PREFIX), ".", - Hex(v & 0x7, Hex::Prefix::OMIT_PREFIX)); - } - }; - - /* try to assign pci device to this protection domain */ - if (!_env.pd().assign_pci(page, rid)) - Genode::error("assignment of PCI device ", Rid(rid), " failed ", - "phys=", Genode::Hex(ds_client.phys_addr()), " " - "virt=", Genode::Hex(page)); - else - Genode::log("assignment of PCI device ", Rid(rid), " succeeded"); - - /* we don't need the mapping anymore */ - _address_space.detach(page); -} - - -struct Main -{ - Genode::Env &env; - - Expanding_region_map_client rm { env }; - - Platform::Device_pd_component pd_component { rm, env }; - - Genode::Static_root root { env.ep().manage(pd_component) }; - - Main(Genode::Env &env) : env(env) - { - env.parent().announce(env.ep().manage(root)); - } -}; - - -/*************** - ** Component ** - ***************/ - -void Component::construct(Genode::Env &env) { static Main main(env); } - diff --git a/repos/os/src/drivers/platform/spec/x86/device_pd/target.mk b/repos/os/src/drivers/platform/spec/x86/device_pd/target.mk deleted file mode 100644 index b00ac918b8..0000000000 --- a/repos/os/src/drivers/platform/spec/x86/device_pd/target.mk +++ /dev/null @@ -1,6 +0,0 @@ -TARGET = device_pd -SRC_CC = main.cc -LIBS = base-nova - -REQUIRES = nova - diff --git a/repos/os/src/drivers/platform/spec/x86/pci_device_pd_ipc.h b/repos/os/src/drivers/platform/spec/x86/pci_device_pd_ipc.h deleted file mode 100644 index 8e863ce4c4..0000000000 --- a/repos/os/src/drivers/platform/spec/x86/pci_device_pd_ipc.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * \brief IPC interface between pci_drv and pci_device_pd - * \author Alexander Boettcher - * \date 2013-02-15 - */ - -/* - * Copyright (C) 2013-2017 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. - */ - -#pragma once - -#include -#include - -#include - -namespace Platform { - - struct Device_pd; - struct Device_pd_client; - struct Device_pd_connection; - struct Device_pd_component; -} - -struct Platform::Device_pd : Genode::Session -{ - static const char *service_name() { return "DEVICE_PD"; } - - enum { CAP_QUOTA = 2 }; - - typedef Device_pd_client Client; - - GENODE_RPC_THROW(Rpc_attach_dma_mem, void, attach_dma_mem, - GENODE_TYPE_LIST(Genode::Out_of_ram, Genode::Out_of_caps), - Genode::Dataspace_capability); - GENODE_RPC_THROW(Rpc_assign_pci, void, assign_pci, - GENODE_TYPE_LIST(Genode::Out_of_ram, Genode::Out_of_caps, - Genode::Region_map::Region_conflict), - Genode::Io_mem_dataspace_capability, Genode::uint16_t); - - GENODE_RPC_INTERFACE(Rpc_attach_dma_mem, Rpc_assign_pci); -}; - -struct Platform::Device_pd_client : Genode::Rpc_client -{ - Device_pd_client(Capability cap) - : Rpc_client(cap) { } - - void attach_dma_mem(Genode::Dataspace_capability cap) { - call(cap); } - - void assign_pci(Genode::Io_mem_dataspace_capability cap, - Genode::uint16_t bdf) - { - call(cap, bdf); - } -}; - -struct Platform::Device_pd_connection : Genode::Connection, Device_pd_client -{ - enum { RAM_QUOTA = 0UL }; - - Device_pd_connection(Genode::Capability cap) - : - Genode::Connection(cap), - Device_pd_client(cap) - { } -}; - -struct Platform::Device_pd_component : Genode::Rpc_object -{ - Genode::Env &_env; - Genode::Region_map &_address_space; - - Device_pd_component(Genode::Region_map &address_space, Genode::Env &env) - : _env(env), _address_space(address_space) { } - - void attach_dma_mem(Genode::Dataspace_capability); - void assign_pci(Genode::Io_mem_dataspace_capability, Genode::uint16_t); -}; diff --git a/repos/os/src/drivers/platform/spec/x86/pci_session_component.h b/repos/os/src/drivers/platform/spec/x86/pci_session_component.h index 6f402bef94..68db4b8f05 100644 --- a/repos/os/src/drivers/platform/spec/x86/pci_session_component.h +++ b/repos/os/src/drivers/platform/spec/x86/pci_session_component.h @@ -15,9 +15,10 @@ /* base */ #include +#include +#include #include #include -#include #include #include @@ -35,7 +36,6 @@ /* local */ #include "pci_device_component.h" #include "pci_config_access.h" -#include "pci_device_pd_ipc.h" #include "device_pd.h" namespace Platform { @@ -199,13 +199,8 @@ class Platform::Session_component : public Genode::Rpc_object private: Genode::Env &_env; - Genode::Rpc_entrypoint &_device_pd_ep; Genode::Attached_rom_dataspace &_config; Genode::Ram_session_guard _env_ram; - Genode::Ram_session_capability _env_ram_cap; - Genode::Pd_session &_env_pd; - Genode::Pd_session_capability _env_pd_cap; - Genode::Region_map &_local_rm; Genode::Heap _md_alloc; Genode::Session_label const _label; Genode::Session_policy const _policy { _label, _config.xml() }; @@ -237,145 +232,7 @@ class Platform::Session_component : public Genode::Rpc_object return false; } - /** - * Deduce specified amount of quota from an allocator guard, or throw - * an 'Out_of_ram' exception if the guard's quota is depleted. - */ - struct Quota_reservation - { - Genode::Ram_session_guard &guard; - - Genode::size_t const amount; - - Quota_reservation(Genode::Ram_session_guard &guard, - Genode::size_t amount) - : guard(guard), amount(amount) - { - if (!guard.withdraw(amount)) - throw Out_of_ram(); - } - - ~Quota_reservation() noexcept(false) - { - if (!guard.revert_withdraw(amount)) - throw Fatal(); - } - }; - - class Device_pd - { - public: - - class Startup_failed : Genode::Exception { }; - - private: - - enum { CAP_QUOTA = 60, RAM_QUOTA = 190 * 4096 }; - - Quota_reservation const _reservation; - Device_pd_policy _policy; - Genode::Child _child; - - void _check_child_started_up() const { - if (!_child.active()) - throw Startup_failed(); } - - bool const _active = (_check_child_started_up(), true); - - Genode::Slave::Connection _connection; - - public: - - /** - * Constructor - * - * \throw Out_of_ram - * \throw Out_of_caps - * \throw Startup_failed child could not be started - * \throw Service_denied by 'Slave::Connection' - */ - Device_pd(Genode::Region_map &local_rm, - Genode::Rpc_entrypoint &ep, - Genode::Ram_session_guard &ref_ram, - Genode::Ram_session_capability ref_ram_cap, - Genode::Pd_session &ref_pd, - Genode::Pd_session_capability ref_pd_cap, - Genode::Session_label const &label) - try : - _reservation(ref_ram, RAM_QUOTA), - _policy(ep, local_rm, ref_pd, ref_pd_cap, - Genode::Cap_quota{CAP_QUOTA}, - Genode::Ram_quota{RAM_QUOTA}, - label), - _child(local_rm, ep, _policy), - _connection(_policy, Genode::Slave::Args()) - { } - /* thrown by 'Quota_reservation', 'Device_pd_policy' or 'Child' */ - catch (Genode::Out_of_ram) { - throw; } - - catch (Genode::Out_of_caps) { - Genode::warning("Out_of_caps during device-pd creation"); - throw; } - - /* thrown by 'Slave::Connection' */ - catch (Genode::Insufficient_ram_quota) { - throw Genode::Out_of_ram(); } - - /* thrown by 'Slave::Connection' */ - catch (Genode::Insufficient_cap_quota) { - Genode::warning("Insufficient_cap_quota during device-pd creation"); - throw Genode::Out_of_caps(); } - - Device_pd_client &session() { return _connection; } - - Genode::Ram_session_capability ram_session_cap() { - return _child.ram_session_cap(); } - }; - - Device_pd *_device_pd = nullptr; - - /** - * Free device PD at session destruction - */ - struct Device_pd_guard - { - Session_component &session; - - ~Device_pd_guard() { - if (session._device_pd) - Genode::destroy(session._md_alloc, session._device_pd); } - - } _device_pd_guard { *this }; - - /** - * Attempt to initialize device PD - * - * \throw Out_of_ram session quota does not suffice to spawn the - * device PD - * \throw Out_of_caps - */ - void _try_init_device_pd() - { - if (_device_pd || _no_device_pd) - return; - - try { - _device_pd = new (_md_alloc) - Device_pd(_local_rm, _device_pd_ep, _env_ram, _env_ram_cap, - _env_pd, _env_pd_cap, _label); - } - catch (Genode::Out_of_ram) { /* thrown by '_md_alloc', 'Device_pd' */ - throw; } - catch (Genode::Out_of_caps) { - Genode::warning("Out_of_caps during Device_pd construction"); - throw; } - catch (...) { - Genode::warning("PCI device protection domain for IOMMU support " - "is not available"); - _no_device_pd = true; - } - } + Platform::Device_pd _device_pd { _env, _label }; enum { MAX_PCI_DEVICES = Device_config::MAX_BUSES * Device_config::MAX_DEVICES * @@ -383,12 +240,11 @@ class Platform::Session_component : public Genode::Rpc_object static Genode::Bit_array bdf_in_use; - - /** * List containing extended PCI config space information */ - static Genode::List &config_space_list() { + static Genode::List &config_space_list() + { static Genode::List config_space; return config_space; } @@ -398,8 +254,7 @@ class Platform::Session_component : public Genode::Rpc_object * the corresponding extended 4K PCI config space address. * A io mem dataspace is created and returned. */ - Genode::addr_t - lookup_config_space(Genode::uint16_t const bdf) + Genode::addr_t lookup_config_space(Genode::uint16_t const bdf) { using namespace Genode; @@ -416,7 +271,8 @@ class Platform::Session_component : public Genode::Rpc_object * List of aliases for PCI Class/Subclas/Prog I/F triple used * by xml config for this platform driver */ - unsigned class_subclass_prog(const char * name) { + unsigned class_subclass_prog(const char * name) + { using namespace Genode; static struct { @@ -591,18 +447,13 @@ class Platform::Session_component : public Genode::Rpc_object */ Session_component(Genode::Env &env, Genode::Attached_rom_dataspace &config, - Genode::Rpc_entrypoint &device_pd_ep, Platform::Pci_buses &buses, Genode::Heap &global_heap, char const *args) : - _env(env), _device_pd_ep(device_pd_ep), + _env(env), _config(config), _env_ram(env.ram(), Genode::ram_quota_from_args(args).value), - _env_ram_cap(env.ram_session_cap()), - _env_pd(env.pd()), - _env_pd_cap(env.pd_session_cap()), - _local_rm(env.rm()), _md_alloc(_env_ram, env.rm()), _label(Genode::label_from_args(args)), _pci_bus(buses), _global_heap(global_heap) @@ -900,17 +751,13 @@ class Platform::Session_component : public Genode::Rpc_object Io_mem_dataspace_capability io_mem = device->get_config_space(); - _try_init_device_pd(); - if (!_device_pd) - return; - try { - _device_pd->session().assign_pci(io_mem, device->config().bdf()); + _device_pd.assign_pci(io_mem, device->config().bdf()); for (Rmrr *r = Rmrr::list()->first(); r; r = r->next()) { Io_mem_dataspace_capability rmrr_cap = r->match(_env, device->config()); if (rmrr_cap.valid()) - _device_pd->session().attach_dma_mem(rmrr_cap); + _device_pd.attach_dma_mem(rmrr_cap); } } catch (...) { Genode::error("assignment to device pd or of RMRR region failed"); @@ -938,13 +785,6 @@ class Platform::Session_component : public Genode::Rpc_object Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t const size) override { - /* - * We always try to create the device PD first because - * otherwise we might consume the requested size multiple - * times which breaks our accounting. - */ - _try_init_device_pd(); - Ram_capability ram_cap; try { ram_cap = _env_ram.alloc(size, Genode::UNCACHED); } @@ -953,13 +793,11 @@ class Platform::Session_component : public Genode::Rpc_object if (!ram_cap.valid()) return ram_cap; - if (_device_pd) { - try { _device_pd->session().attach_dma_mem(ram_cap); } - catch (Out_of_ram) { _rollback(size, ram_cap);; } - catch (Out_of_caps) { - Genode::warning("Out_of_caps while attaching DMA memory"); - _rollback(size, ram_cap);; - } + try { _device_pd.attach_dma_mem(ram_cap); } + catch (Out_of_ram) { _rollback(size, ram_cap);; } + catch (Out_of_caps) { + Genode::warning("Out_of_caps while attaching DMA memory"); + _rollback(size, ram_cap);; } try { _insert(ram_cap); } @@ -1014,7 +852,6 @@ class Platform::Root : public Genode::Root_component Genode::Reporter _pci_reporter { _env, "pci" }; - Genode::Rpc_entrypoint _device_pd_ep; Genode::Heap _heap { _env.ram(), _env.rm() }; Platform::Pci_buses _buses { _env, _heap }; @@ -1061,7 +898,7 @@ class Platform::Root : public Genode::Root_component } if (node.has_type("rmrr")) { - uint64_t mem_start, mem_end; + uint64_t mem_start = 0, mem_end = 0; node.attribute("start").value(&mem_start); node.attribute("end").value(&mem_end); @@ -1076,7 +913,7 @@ class Platform::Root : public Genode::Root_component if (!scope.num_sub_nodes() || !scope.has_type("scope")) throw 3; - unsigned bus, dev, func; + unsigned bus = 0, dev = 0, func = 0; scope.attribute("bus_start").value(&bus); for (unsigned p = 0; p < scope.num_sub_nodes(); p++) { @@ -1152,7 +989,7 @@ class Platform::Root : public Genode::Root_component { try { return new (md_alloc()) - Session_component(_env, _config, _device_pd_ep, _buses, _heap, args); + Session_component(_env, _config, _buses, _heap, args); } catch (Genode::Session_policy::No_policy_defined) { Genode::error("Invalid session request, no matching policy for ", @@ -1184,8 +1021,7 @@ class Platform::Root : public Genode::Root_component : Genode::Root_component(&env.ep().rpc_ep(), &md_alloc), - _env(env), _config(config), - _device_pd_ep(&env.pd(), STACK_SIZE, "device_pd_slave") + _env(env), _config(config) { if (acpi_rom) { try { diff --git a/repos/os/src/drivers/platform/spec/x86/target.mk b/repos/os/src/drivers/platform/spec/x86/target.mk index a4adbab134..01c92e9944 100644 --- a/repos/os/src/drivers/platform/spec/x86/target.mk +++ b/repos/os/src/drivers/platform/spec/x86/target.mk @@ -1,6 +1,7 @@ TARGET = platform_drv REQUIRES = x86 SRC_CC = main.cc irq.cc pci_device.cc nonpci_devices.cc session.cc +SRC_CC += device_pd.cc LIBS = base INC_DIR = $(PRG_DIR)