pci: provide io mem via device interface

Fixes #1487
This commit is contained in:
Alexander Boettcher 2015-04-12 13:01:19 +02:00 committed by Christian Helmuth
parent f265b64d6d
commit 65a3be856f
6 changed files with 64 additions and 5 deletions

View File

@ -53,6 +53,9 @@ struct Pci::Device_client : public Genode::Rpc_client<Device>
Genode::Io_port_session_capability io_port(Genode::uint8_t id) override {
return call<Rpc_io_port>(id); }
Genode::Io_mem_session_capability io_mem(Genode::uint8_t id) override {
return call<Rpc_io_mem>(id); }
};
#endif /* _INCLUDE__PCI_DEVICE__CLIENT_H_ */

View File

@ -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_bus_address,
Genode::Meta::Type_tuple<Rpc_vendor_id,
@ -251,8 +254,9 @@ struct Pci::Device : Platform::Device
Genode::Meta::Type_tuple<Rpc_config_write,
Genode::Meta::Type_tuple<Rpc_irq,
Genode::Meta::Type_tuple<Rpc_io_port,
Genode::Meta::Type_tuple<Rpc_io_mem,
Genode::Meta::Empty>
> > > > > > > > Rpc_functions;
> > > > > > > > > Rpc_functions;
};
#endif /* _INCLUDE__PCI_DEVICE__PCI_DEVICE_H_ */

View File

@ -14,6 +14,7 @@
#pragma once
#include <irq_session/capability.h>
#include <io_mem_session/capability.h>
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;
};

View File

@ -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();
}
};

View File

@ -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();
}

View File

@ -48,7 +48,12 @@ class Pci::Device_component : public Genode::Rpc_object<Pci::Device>,
Genode::Slab_block _slab_ioport_block;
char _slab_ioport_block_data[IO_BLOCK_SIZE];
Genode::Tslab<Genode::Io_mem_connection, IO_BLOCK_SIZE> _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<Pci::Device>,
_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<Pci::Device>,
:
_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<Pci::Device>,
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<Pci::Device>,
}
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_ */