/* * \brief PCI-bus driver * \author Norman Feske * \date 2008-01-28 */ /* * Copyright (C) 2008-2013 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. */ #include #include #include #include #include #include "pci_session_component.h" #include "pci_device_config.h" using namespace Genode; using namespace Pci; class Device_pd_policy : public Genode::Slave_policy { private: Genode::Root_capability _cap; Genode::Lock _lock; protected: char const **_permitted_services() const { static char const *permitted_services[] = { "LOG", "CAP", "RM", "CPU", 0 }; return permitted_services; }; public: Device_pd_policy(Genode::Rpc_entrypoint &slave_ep) : Slave_policy("pci_device_pd", slave_ep), _lock(Genode::Lock::LOCKED) { } bool announce_service(const char *service_name, Genode::Root_capability root, Genode::Allocator *alloc, Genode::Server *server) { /* wait for 'pci_drv' to announce the PCI service */ if (Genode::strcmp(service_name, "PCI_DEV_PD")) return false; _cap = root; _lock.unlock(); return true; } Genode::Root_capability root() { if (!_cap.valid()) _lock.lock(); return _cap; } }; int main(int argc, char **argv) { printf("PCI driver started\n"); /* * Initialize server entry point */ enum { STACK_SIZE = 2 * sizeof(addr_t)*1024, PCI_DEVICE_PD_RAM_QUOTA = sizeof(addr_t) * 128 * 1024, }; static Cap_connection cap; static Rpc_entrypoint ep(&cap, STACK_SIZE, "pci_ep"); /* use 'pci_device_pd' as slave service */ Session_capability session_dev_pd; try { static Rpc_entrypoint device_pd_ep(&cap, STACK_SIZE, "device_pd_slave"); static Device_pd_policy device_pd_policy(device_pd_ep); static Genode::Slave device_pd_slave(device_pd_ep, device_pd_policy, PCI_DEVICE_PD_RAM_QUOTA); session_dev_pd = Genode::Root_client(device_pd_policy.root()).session(""); } catch (...) { PWRN("PCI device protection domain for IOMMU support is not available"); } /* * Use sliced heap to allocate each session component at a separate * dataspace. */ static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session()); /* * Let the entry point serve the PCI root interface */ static Pci::Root root(&ep, &sliced_heap, PCI_DEVICE_PD_RAM_QUOTA, Genode::reinterpret_cap_cast(session_dev_pd)); env()->parent()->announce(ep.manage(&root)); sleep_forever(); return 0; }