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 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_mmio_mapping(Resources &resources, Ggtt::Offset offset, size_t size)
Ggtt::Offset offset)
: :
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; Ggtt::Mapping::offset = offset;
} }
@ -310,12 +310,9 @@ struct Igd::Device
* Create the mapping first and insert the entries afterwards * Create the mapping first and insert the entries afterwards
* so we do not have to rollback when the allocation failes. * 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> *mem = new (&alloc)
Genode::Registered<Ggtt_mmio_mapping>(_ggtt_mmio_mapping_registry, 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) { for (size_t i = 0; i < size; i += PAGE_SIZE) {
addr_t const pa = phys_addr + i; addr_t const pa = phys_addr + i;
_ggtt->insert_pte(pa, offset + (i / PAGE_SIZE)); _ggtt->insert_pte(pa, offset + (i / PAGE_SIZE));
@ -1383,6 +1380,11 @@ struct Igd::Device
Ggtt::Mapping const &map_buffer(Genode::Allocator &guard, Ggtt::Mapping const &map_buffer(Genode::Allocator &guard,
Genode::Dataspace_capability cap, bool aperture) 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 size = Genode::Dataspace_client(cap).size();
size_t const num = size / PAGE_SIZE; size_t const num = size / PAGE_SIZE;
Ggtt::Offset const offset = _ggtt->find_free(num, aperture); Ggtt::Offset const offset = _ggtt->find_free(num, aperture);

View File

@ -17,6 +17,7 @@ namespace Platform {
class Device_component; class Device_component;
class Session_component; class Session_component;
class Io_mem_session_component; class Io_mem_session_component;
class Io_mem_session_component_gmadr;
class Irq_session_component; class Irq_session_component;
class Root; 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> class Platform::Device_component : public Rpc_object<Device>
{ {
private: private:
@ -89,7 +109,7 @@ class Platform::Device_component : public Rpc_object<Device>
Device_client &_device { _resources.gpu_client() }; Device_client &_device { _resources.gpu_client() };
Io_mem_session_component _gttmmadr_io { _resources }; Io_mem_session_component _gttmmadr_io { _resources };
Constructible<Io_mem_connection> _gmadr_io { }; Io_mem_session_component_gmadr _gmadr_io { _resources };
Irq_session_component _irq { _resources }; Irq_session_component _irq { _resources };
public: public:
@ -99,12 +119,14 @@ class Platform::Device_component : public Rpc_object<Device>
_env(env), _resources(resources) _env(env), _resources(resources)
{ {
_env.ep().rpc_ep().manage(&_gttmmadr_io); _env.ep().rpc_ep().manage(&_gttmmadr_io);
_env.ep().rpc_ep().manage(&_gmadr_io);
_env.ep().rpc_ep().manage(&_irq); _env.ep().rpc_ep().manage(&_irq);
} }
~Device_component() ~Device_component()
{ {
_env.ep().rpc_ep().dissolve(&_gttmmadr_io); _env.ep().rpc_ep().dissolve(&_gttmmadr_io);
_env.ep().rpc_ep().dissolve(&_gmadr_io);
_env.ep().rpc_ep().dissolve(&_irq); _env.ep().rpc_ep().dissolve(&_irq);
} }
@ -113,22 +135,15 @@ class Platform::Device_component : public Rpc_object<Device>
return _irq.cap(); 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 */, addr_t /* offset */,
size_t /* size */) override size_t /* size */) override
{ {
if (v_id == 0) if (v_id == 0)
return _gttmmadr_io.cap(); return _gttmmadr_io.cap();
if (v_id == 1) { if (v_id == 1)
if (!_gmadr_io.constructed()) { return _gmadr_io.cap();
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();
}
return Io_mem_session_capability(); 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_connection = Genode::Io_mem_connection;
using Io_mem_dataspace_capability = Genode::Io_mem_dataspace_capability; using Io_mem_dataspace_capability = Genode::Io_mem_dataspace_capability;
using Ram_dataspace_capability = Genode::Ram_dataspace_capability; using Ram_dataspace_capability = Genode::Ram_dataspace_capability;
using Dataspace_capability = Genode::Dataspace_capability;
Genode::Env &_env; Genode::Env &_env;
Genode::Heap &_heap; Genode::Heap &_heap;
@ -84,10 +85,15 @@ class Igd::Resources : Genode::Noncopyable
GTT_RESERVED = (APERTURE_RESERVED/PAGE_SIZE) * 8, GTT_RESERVED = (APERTURE_RESERVED/PAGE_SIZE) * 8,
}; };
Genode::Rm_connection _rm_connection { _env };
Platform::Device::Resource _gmadr { }; 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 */ /* managed dataspace for local platform service */
Genode::Rm_connection _rm_connection { _env };
Genode::Constructible<Genode::Region_map_client> _gttmmadr_rm { }; Genode::Constructible<Genode::Region_map_client> _gttmmadr_rm { };
void _create_gttmmadr_rm() void _create_gttmmadr_rm()
@ -236,11 +242,14 @@ class Igd::Resources : Genode::Noncopyable
_gpu_client.construct(_gpu_cap); _gpu_client.construct(_gpu_cap);
_gttmmadr = _gpu_client->resource(0); _gttmmadr = _gpu_client->resource(0);
_gmadr = _gpu_client->resource(2);
_gttmmadr_io.construct(_env, _gttmmadr.base(), _gttmmadr.size()); _gttmmadr_io.construct(_env, _gttmmadr.base(), _gttmmadr.size());
_gttmmadr_ds = _gttmmadr_io->dataspace(); _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(); _enable_pci_bus_master();
log("Reserved beginning ", log("Reserved beginning ",
@ -254,6 +263,8 @@ class Igd::Resources : Genode::Noncopyable
_platform.release_device(_host_bridge_cap); _platform.release_device(_host_bridge_cap);
} }
Genode::Rm_connection &rm() { return _rm_connection; }
addr_t map_gttmmadr() addr_t map_gttmmadr()
{ {
if (!_gttmmadr_ds.valid()) if (!_gttmmadr_ds.valid())
@ -304,6 +315,8 @@ class Igd::Resources : Genode::Noncopyable
addr_t gmadr_base() const { return _gmadr.base(); } addr_t gmadr_base() const { return _gmadr.base(); }
size_t gmadr_size() const { return _gmadr.size(); } size_t gmadr_size() const { return _gmadr.size(); }
Dataspace_capability gmadr_ds() const { return _gmadr_ds; }
addr_t gttmmadr_base() const { return _gttmmadr.base(); } addr_t gttmmadr_base() const { return _gttmmadr.base(); }
size_t gttmmadr_size() const { return _gttmmadr.size(); } 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()); 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() void gtt_platform_reset()
{ {
addr_t const base = map_gttmmadr() + (gttmmadr_size() / 2); addr_t const base = map_gttmmadr() + (gttmmadr_size() / 2);