gpu/intel: use managed dataspace for aperture mappings

Use 'Region_map_client' for aperture mappings through the GGTT instead
of 'Io_mem_connections'.

issue #4284
This commit is contained in:
Sebastian Sumpf 2021-10-11 11:57:56 +02:00 committed by Norman Feske
parent 440debfc39
commit c79cdc7b39
3 changed files with 64 additions and 28 deletions

View File

@ -282,14 +282,14 @@ struct Igd::Device
struct Ggtt_mmio_mapping : Ggtt::Mapping
{
Genode::Io_mem_connection mmio;
Region_map_client _rm;
Ggtt_mmio_mapping(Genode::Env &env, addr_t base, size_t size,
Ggtt::Offset offset)
Ggtt_mmio_mapping(Resources &resources, Ggtt::Offset offset, size_t size)
:
mmio(env, base, size)
_rm(resources.rm().create(size))
{
Ggtt::Mapping::cap = mmio.dataspace();
_rm.attach_at(resources.gmadr_ds(), 0, size, offset * PAGE_SIZE);
Ggtt::Mapping::cap = _rm.dataspace();
Ggtt::Mapping::offset = offset;
}
@ -310,12 +310,9 @@ struct Igd::Device
* Create the mapping first and insert the entries afterwards
* so we do not have to rollback when the allocation failes.
*/
addr_t const base = _resources.gmadr_base() + _ggtt->addr(offset);
Genode::Registered<Ggtt_mmio_mapping> *mem = new (&alloc)
Genode::Registered<Ggtt_mmio_mapping>(_ggtt_mmio_mapping_registry,
_env, base, size, offset);
_resources, offset, size);
for (size_t i = 0; i < size; i += PAGE_SIZE) {
addr_t const pa = phys_addr + i;
_ggtt->insert_pte(pa, offset + (i / PAGE_SIZE));
@ -1383,6 +1380,11 @@ struct Igd::Device
Ggtt::Mapping const &map_buffer(Genode::Allocator &guard,
Genode::Dataspace_capability cap, bool aperture)
{
if (aperture == false) {
error("GGTT mapping outside aperture");
throw Could_not_map_buffer();
}
size_t const size = Genode::Dataspace_client(cap).size();
size_t const num = size / PAGE_SIZE;
Ggtt::Offset const offset = _ggtt->find_free(num, aperture);

View File

@ -17,6 +17,7 @@ namespace Platform {
class Device_component;
class Session_component;
class Io_mem_session_component;
class Io_mem_session_component_gmadr;
class Irq_session_component;
class Root;
}
@ -80,6 +81,25 @@ class Platform::Io_mem_session_component : public Rpc_object<Io_mem_session>
};
class Platform::Io_mem_session_component_gmadr : public Rpc_object<Io_mem_session>
{
private:
Igd::Resources &_resources;
public:
Io_mem_session_component_gmadr(Igd::Resources &resources)
:
_resources(resources) { }
Io_mem_dataspace_capability dataspace() override
{
return _resources.gmadr_platform_ds();
}
};
class Platform::Device_component : public Rpc_object<Device>
{
private:
@ -88,9 +108,9 @@ class Platform::Device_component : public Rpc_object<Device>
Igd::Resources &_resources;
Device_client &_device { _resources.gpu_client() };
Io_mem_session_component _gttmmadr_io { _resources };
Constructible<Io_mem_connection> _gmadr_io { };
Irq_session_component _irq { _resources };
Io_mem_session_component _gttmmadr_io { _resources };
Io_mem_session_component_gmadr _gmadr_io { _resources };
Irq_session_component _irq { _resources };
public:
@ -99,12 +119,14 @@ class Platform::Device_component : public Rpc_object<Device>
_env(env), _resources(resources)
{
_env.ep().rpc_ep().manage(&_gttmmadr_io);
_env.ep().rpc_ep().manage(&_gmadr_io);
_env.ep().rpc_ep().manage(&_irq);
}
~Device_component()
{
_env.ep().rpc_ep().dissolve(&_gttmmadr_io);
_env.ep().rpc_ep().dissolve(&_gmadr_io);
_env.ep().rpc_ep().dissolve(&_irq);
}
@ -113,22 +135,15 @@ class Platform::Device_component : public Rpc_object<Device>
return _irq.cap();
}
Io_mem_session_capability io_mem(uint8_t v_id, Cache caching,
Io_mem_session_capability io_mem(uint8_t v_id, Cache /* caching */,
addr_t /* offset */,
size_t /* size */) override
{
if (v_id == 0)
return _gttmmadr_io.cap();
if (v_id == 1) {
if (!_gmadr_io.constructed()) {
bool write_combined = (caching == WRITE_COMBINED) ? true : false;
_gmadr_io.construct(_env, _resources.gmadr_base(),
_resources.gmadr_platform_size(), write_combined);
}
return _gmadr_io->cap();
}
if (v_id == 1)
return _gmadr_io.cap();
return Io_mem_session_capability();
}

View File

@ -32,6 +32,7 @@ class Igd::Resources : Genode::Noncopyable
using Io_mem_connection = Genode::Io_mem_connection;
using Io_mem_dataspace_capability = Genode::Io_mem_dataspace_capability;
using Ram_dataspace_capability = Genode::Ram_dataspace_capability;
using Dataspace_capability = Genode::Dataspace_capability;
Genode::Env &_env;
Genode::Heap &_heap;
@ -84,10 +85,15 @@ class Igd::Resources : Genode::Noncopyable
GTT_RESERVED = (APERTURE_RESERVED/PAGE_SIZE) * 8,
};
Platform::Device::Resource _gmadr { };
Genode::Rm_connection _rm_connection { _env };
Platform::Device::Resource _gmadr { };
Io_mem_dataspace_capability _gmadr_ds { };
Genode::Constructible<Io_mem_connection> _gmadr_io { };
Genode::Region_map_client _gmadr_rm { _rm_connection.create(APERTURE_RESERVED) };
/* managed dataspace for local platform service */
Genode::Rm_connection _rm_connection { _env };
Genode::Constructible<Genode::Region_map_client> _gttmmadr_rm { };
void _create_gttmmadr_rm()
@ -236,11 +242,14 @@ class Igd::Resources : Genode::Noncopyable
_gpu_client.construct(_gpu_cap);
_gttmmadr = _gpu_client->resource(0);
_gmadr = _gpu_client->resource(2);
_gttmmadr_io.construct(_env, _gttmmadr.base(), _gttmmadr.size());
_gttmmadr_ds = _gttmmadr_io->dataspace();
_gmadr = _gpu_client->resource(2);
_gmadr_io.construct(_env, _gmadr.base(), _gmadr.size(), true);
_gmadr_ds = _gmadr_io->dataspace();
_gmadr_rm.attach_at(_gmadr_ds, 0, APERTURE_RESERVED);
_enable_pci_bus_master();
log("Reserved beginning ",
@ -254,6 +263,8 @@ class Igd::Resources : Genode::Noncopyable
_platform.release_device(_host_bridge_cap);
}
Genode::Rm_connection &rm() { return _rm_connection; }
addr_t map_gttmmadr()
{
if (!_gttmmadr_ds.valid())
@ -302,8 +313,10 @@ class Igd::Resources : Genode::Noncopyable
Platform::Device_capability isa_bridge_cap() { return _isa_bridge_cap; }
unsigned isa_bridge_class() const { return 0x601u << 8; }
addr_t gmadr_base() const { return _gmadr.base(); }
size_t gmadr_size() const { return _gmadr.size(); }
addr_t gmadr_base() const { return _gmadr.base(); }
size_t gmadr_size() const { return _gmadr.size(); }
Dataspace_capability gmadr_ds() const { return _gmadr_ds; }
addr_t gttmmadr_base() const { return _gttmmadr.base(); }
size_t gttmmadr_size() const { return _gttmmadr.size(); }
@ -323,6 +336,12 @@ class Igd::Resources : Genode::Noncopyable
return static_cap_cast<Io_mem_dataspace>(_gttmmadr_rm->dataspace());
}
Io_mem_dataspace_capability gmadr_platform_ds()
{
using namespace Genode;
return static_cap_cast<Io_mem_dataspace>(_gmadr_rm.dataspace());
}
void gtt_platform_reset()
{
addr_t const base = map_gttmmadr() + (gttmmadr_size() / 2);