diff --git a/repos/base-nova/include/pd_session/client.h b/repos/base-nova/include/pd_session/client.h index 18f78dc7e..9a29860dd 100644 --- a/repos/base-nova/include/pd_session/client.h +++ b/repos/base-nova/include/pd_session/client.h @@ -33,8 +33,8 @@ namespace Genode { return call(parent); } - bool assign_pci(addr_t pci_config_memory_address) { - return call(pci_config_memory_address); } + bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) { + return call(pci_config_memory_address, bdf); } }; } diff --git a/repos/base-nova/include/pd_session/pd_session.h b/repos/base-nova/include/pd_session/pd_session.h index 41e3e7776..efa573acc 100644 --- a/repos/base-nova/include/pd_session/pd_session.h +++ b/repos/base-nova/include/pd_session/pd_session.h @@ -49,7 +49,15 @@ namespace Genode { virtual int assign_parent(Parent_capability parent) = 0; - virtual bool assign_pci(addr_t) = 0; + /** + * Assign PCI device to a protection domain. + * + * \param pci_config_space virtual address of the 4K PCI config + * space extended memory of the device + * \param bdf bus/device/function of the PCI device + * \return true on success, or false in case of an error + */ + virtual bool assign_pci(addr_t pci_config_space, uint16_t bdf) = 0; /********************* ** RPC declaration ** @@ -57,7 +65,7 @@ namespace Genode { GENODE_RPC(Rpc_bind_thread, int, bind_thread, Thread_capability); GENODE_RPC(Rpc_assign_parent, int, assign_parent, Parent_capability); - GENODE_RPC(Rpc_assign_pci, bool, assign_pci, addr_t); + GENODE_RPC(Rpc_assign_pci, bool, assign_pci, addr_t, uint16_t); GENODE_RPC_INTERFACE(Rpc_bind_thread, Rpc_assign_parent, Rpc_assign_pci); diff --git a/repos/base-nova/src/core/include/pd_session_component.h b/repos/base-nova/src/core/include/pd_session_component.h index 67152bde8..57fb318b9 100644 --- a/repos/base-nova/src/core/include/pd_session_component.h +++ b/repos/base-nova/src/core/include/pd_session_component.h @@ -70,7 +70,7 @@ namespace Genode { int bind_thread(Thread_capability); int assign_parent(Parent_capability); - bool assign_pci(addr_t); + bool assign_pci(addr_t, uint16_t); }; } diff --git a/repos/base-nova/src/core/pd_session_extension.cc b/repos/base-nova/src/core/pd_session_extension.cc index a0f38f025..f90c3de2c 100644 --- a/repos/base-nova/src/core/pd_session_extension.cc +++ b/repos/base-nova/src/core/pd_session_extension.cc @@ -17,8 +17,8 @@ using namespace Genode; -bool Pd_session_component::assign_pci(addr_t pci_config_memory) +bool Pd_session_component::assign_pci(addr_t pci_config_memory, uint16_t bdf) { - uint8_t res = Nova::assign_pci(_pd.pd_sel(), pci_config_memory, 0); + uint8_t res = Nova::assign_pci(_pd.pd_sel(), pci_config_memory, bdf); return res == Nova::NOVA_OK; } 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 index 0c30e20ce..8d4f206f9 100644 --- a/repos/os/src/drivers/platform/spec/x86/device_pd/main.cc +++ b/repos/os/src/drivers/platform/spec/x86/device_pd/main.cc @@ -127,7 +127,7 @@ void Platform::Device_pd_component::attach_dma_mem(Genode::Dataspace_capability } } -void Platform::Device_pd_component::assign_pci(Genode::Io_mem_dataspace_capability io_mem_cap) +void Platform::Device_pd_component::assign_pci(Genode::Io_mem_dataspace_capability io_mem_cap, Genode::uint16_t rid) { using namespace Genode; @@ -143,8 +143,10 @@ void Platform::Device_pd_component::assign_pci(Genode::Io_mem_dataspace_capabili PERR("assignment of PCI device failed - %lx", page); /* try to assign pci device to this protection domain */ - if (!env()->pd_session()->assign_pci(page)) - PERR("assignment of PCI device failed"); + if (!env()->pd_session()->assign_pci(page, rid)) + PERR("assignment of PCI device %x:%x.%x failed phys=%lx virt=%lx", + rid >> 8, (rid >> 3) & 0x1f, rid & 0x7, + ds_client.phys_addr(), page); /* we don't need the mapping anymore */ rm_session()->detach(page); diff --git a/repos/os/src/drivers/platform/spec/x86/pci_device_config.h b/repos/os/src/drivers/platform/spec/x86/pci_device_config.h index bab1f2d3a..e3c0f36b7 100644 --- a/repos/os/src/drivers/platform/spec/x86/pci_device_config.h +++ b/repos/os/src/drivers/platform/spec/x86/pci_device_config.h @@ -143,6 +143,9 @@ namespace Platform { int device_number() { return _device; } int function_number() { return _function; } + Genode::uint16_t bdf () { + return (_bus << 8) | (_device << 3) | (_function & 0x7); } + /** * Accessor functions for device information */ 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 index 6cf7bcde0..097095977 100644 --- 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 @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2013-2015 Genode Labs GmbH + * Copyright (C) 2013-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -18,6 +18,7 @@ #include namespace Platform { + struct Device_pd; struct Device_pd_client; struct Device_pd_component; @@ -33,7 +34,7 @@ struct Platform::Device_pd : Genode::Session GENODE_RPC_THROW(Rpc_assign_pci, void, assign_pci, GENODE_TYPE_LIST(Genode::Rm_session::Out_of_metadata, Genode::Rm_session::Region_conflict), - Genode::Io_mem_dataspace_capability); + Genode::Io_mem_dataspace_capability, Genode::uint16_t); GENODE_RPC_INTERFACE(Rpc_attach_dma_mem, Rpc_assign_pci); }; @@ -41,19 +42,21 @@ struct Platform::Device_pd : Genode::Session struct Platform::Device_pd_client : Genode::Rpc_client { Device_pd_client(Capability cap) - : - Rpc_client(cap) { } + : Rpc_client(cap) { } void attach_dma_mem(Genode::Dataspace_capability cap) { call(cap); } - void assign_pci(Genode::Io_mem_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_component : Genode::Rpc_object { void attach_dma_mem(Genode::Dataspace_capability); - void assign_pci(Genode::Io_mem_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 c7487a722..acca4edc8 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 @@ -266,12 +266,10 @@ namespace Platform { * A io mem dataspace is created and returned. */ Genode::addr_t - lookup_config_space(Genode::uint8_t bus, Genode::uint8_t dev, - Genode::uint8_t func) + lookup_config_space(Genode::uint16_t const bdf) { using namespace Genode; - uint32_t bdf = (bus << 8) | ((dev & 0x1f) << 3) | (func & 0x7); addr_t config_space = ~0UL; /* invalid */ Config_space *e = config_space_list().first(); @@ -670,7 +668,7 @@ namespace Platform { /* lookup if we have a extended pci config space */ Genode::addr_t config_space = - lookup_config_space(bus, device, function); + lookup_config_space(config.bdf()); /* * A device was found. Create a new device component for the @@ -753,7 +751,7 @@ namespace Platform { return; try { - _device_pd->child.assign_pci(io_mem); + _device_pd->child.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(device->config());