diff --git a/repos/os/include/pci_device/client.h b/repos/os/include/pci_device/client.h index 982c64bba..7c0918c5e 100644 --- a/repos/os/include/pci_device/client.h +++ b/repos/os/include/pci_device/client.h @@ -53,6 +53,9 @@ struct Pci::Device_client : public Genode::Rpc_client Genode::Io_port_session_capability io_port(Genode::uint8_t id) override { return call(id); } + + Genode::Io_mem_session_capability io_mem(Genode::uint8_t id) override { + return call(id); } }; #endif /* _INCLUDE__PCI_DEVICE__CLIENT_H_ */ diff --git a/repos/os/include/pci_device/pci_device.h b/repos/os/include/pci_device/pci_device.h index ca2094d5a..045f890ef 100644 --- a/repos/os/include/pci_device/pci_device.h +++ b/repos/os/include/pci_device/pci_device.h @@ -241,6 +241,9 @@ struct Pci::Device : Platform::Device GENODE_RPC_THROW(Rpc_io_port, Genode::Io_port_session_capability, io_port, GENODE_TYPE_LIST(Quota_exceeded), Genode::uint8_t); + GENODE_RPC_THROW(Rpc_io_mem, Genode::Io_mem_session_capability, io_mem, + GENODE_TYPE_LIST(Quota_exceeded), + Genode::uint8_t); typedef Genode::Meta::Type_tuple - > > > > > > > > Rpc_functions; + > > > > > > > > > Rpc_functions; }; #endif /* _INCLUDE__PCI_DEVICE__PCI_DEVICE_H_ */ diff --git a/repos/os/include/platform/device.h b/repos/os/include/platform/device.h index 4848ad810..b58228d81 100644 --- a/repos/os/include/platform/device.h +++ b/repos/os/include/platform/device.h @@ -14,6 +14,7 @@ #pragma once #include +#include namespace Platform { class Device; } @@ -23,4 +24,9 @@ struct Platform::Device * Get IRQ session capability */ virtual Genode::Irq_session_capability irq(Genode::uint8_t) = 0; + + /** + * Get IO mem session capability of specified resource id + */ + virtual Genode::Io_mem_session_capability io_mem(Genode::uint8_t) = 0; }; diff --git a/repos/os/src/drivers/pci/nonpci_devices.cc b/repos/os/src/drivers/pci/nonpci_devices.cc index a10461306..923cb39f4 100644 --- a/repos/os/src/drivers/pci/nonpci_devices.cc +++ b/repos/os/src/drivers/pci/nonpci_devices.cc @@ -63,6 +63,11 @@ class Nonpci::Ps2 : public Pci::Device_component return Genode::Io_port_session_capability(); } + + Genode::Io_mem_session_capability io_mem(Genode::uint8_t) override + { + return Genode::Io_mem_session_capability(); + } }; diff --git a/repos/os/src/drivers/pci/pci_device.cc b/repos/os/src/drivers/pci/pci_device.cc index e76e84f27..5fefcdea3 100644 --- a/repos/os/src/drivers/pci/pci_device.cc +++ b/repos/os/src/drivers/pci/pci_device.cc @@ -36,3 +36,27 @@ Genode::Io_port_session_capability Pci::Device_component::io_port(Genode::uint8_ return Genode::Io_port_session_capability(); } + +Genode::Io_mem_session_capability Pci::Device_component::io_mem(Genode::uint8_t v_id) +{ + Genode::uint8_t max = sizeof(_io_mem_conn) / sizeof(_io_mem_conn[0]); + Genode::uint8_t i = 0, r_id = 0; + + for (Resource res = resource(0); i < max; i++, res = resource(i)) + { + if (res.type() != Resource::MEMORY) + continue; + + if (v_id != r_id) { + r_id ++; + continue; + } + + if (_io_mem_conn[v_id] == nullptr) + _io_mem_conn[v_id] = new (_slab_iomem) Genode::Io_mem_connection(res.base(), res.size()); + + return _io_mem_conn[v_id]->cap(); + } + + return Genode::Io_mem_session_capability(); +} diff --git a/repos/os/src/drivers/pci/pci_device_component.h b/repos/os/src/drivers/pci/pci_device_component.h index 8e0a099f7..edbb734ff 100644 --- a/repos/os/src/drivers/pci/pci_device_component.h +++ b/repos/os/src/drivers/pci/pci_device_component.h @@ -48,7 +48,12 @@ class Pci::Device_component : public Genode::Rpc_object, Genode::Slab_block _slab_ioport_block; char _slab_ioport_block_data[IO_BLOCK_SIZE]; + Genode::Tslab _slab_iomem; + Genode::Slab_block _slab_iomem_block; + char _slab_iomem_block_data[IO_BLOCK_SIZE]; + Genode::Io_port_connection *_io_port_conn [Device::NUM_RESOURCES]; + Genode::Io_mem_connection *_io_mem_conn [Device::NUM_RESOURCES]; enum { PCI_IRQ = 0x3c }; @@ -65,15 +70,20 @@ class Pci::Device_component : public Genode::Rpc_object, _io_mem(0), _ep(ep), _session(session), _irq_session(_device_config.read(&_config_access, PCI_IRQ, Pci::Device::ACCESS_8BIT)), - _slab_ioport(0, &_slab_ioport_block) + _slab_ioport(0, &_slab_ioport_block), + _slab_iomem(0, &_slab_iomem_block) { _ep->manage(&_irq_session); - for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) + for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) { _io_port_conn[i] = nullptr; + _io_mem_conn[i] = nullptr; + } if (_slab_ioport.num_elem() != Device::NUM_RESOURCES) PERR("incorrect amount of space for io port resources"); + if (_slab_iomem.num_elem() != Device::NUM_RESOURCES) + PERR("incorrect amount of space for io mem resources"); } /** @@ -84,12 +94,15 @@ class Pci::Device_component : public Genode::Rpc_object, : _config_space(~0UL), _io_mem(0), _ep(ep), _session(session), _irq_session(irq), - _slab_ioport(0, &_slab_ioport_block) + _slab_ioport(0, &_slab_ioport_block), + _slab_iomem(0, &_slab_iomem_block) { _ep->manage(&_irq_session); - for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) + for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) { _io_port_conn[i] = nullptr; + _io_mem_conn[i] = nullptr; + } } /** @@ -102,6 +115,8 @@ class Pci::Device_component : public Genode::Rpc_object, for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) { if (_io_port_conn[i]) Genode::destroy(_slab_ioport, _io_port_conn[i]); + if (_io_mem_conn[i]) + Genode::destroy(_slab_iomem, _io_mem_conn[i]); } } @@ -167,6 +182,8 @@ class Pci::Device_component : public Genode::Rpc_object, } Genode::Io_port_session_capability io_port(Genode::uint8_t) override; + + Genode::Io_mem_session_capability io_mem(Genode::uint8_t) override; }; #endif /* _PCI_DEVICE_COMPONENT_H_ */