diff --git a/repos/os/src/drivers/gpu/intel/main.cc b/repos/os/src/drivers/gpu/intel/main.cc index 0a365d64fb..21d2b6d905 100644 --- a/repos/os/src/drivers/gpu/intel/main.cc +++ b/repos/os/src/drivers/gpu/intel/main.cc @@ -598,7 +598,7 @@ struct Igd::Device struct Vgpu : Genode::Fifo::Element { enum { - APERTURE_SIZE = 4096ul, + DUMMY_MESA_APERTURE_SIZE = 4096ul, MAX_FENCES = 16, INFO_SIZE = 4096, @@ -635,7 +635,7 @@ struct Igd::Device _device.vgpu_created(); _info = Gpu::Info_intel(_device.id(), _device.features(), - APERTURE_SIZE, + DUMMY_MESA_APERTURE_SIZE, _id, Gpu::Sequence_number { .value = 0 }, _device._revision, _device._slice_mask, @@ -1281,14 +1281,15 @@ struct Igd::Device _ggtt.construct(plat_con, mmio, ggtt_base, _ggtt_size(gmch_ctl), gmadr.size(), - APERTURE_RESERVED); + _resources.aperture_reserved()); if (!_supported(mmio, supported, device_id, revision)) throw Unsupported_device(); _ggtt->dump(); - _vgpu_avail = (gmadr.size() - APERTURE_RESERVED) / Vgpu::APERTURE_SIZE; + _vgpu_avail = (gmadr.size() - _resources.aperture_reserved()) + / Vgpu::DUMMY_MESA_APERTURE_SIZE; reinit(mmio); }); @@ -2503,7 +2504,8 @@ struct Main : Irq_ack_handler, Gpu_reset_handler &Main::handle_irq }; Signal_handler
_config_sigh { _env.ep(), *this, &Main::_handle_config_update }; - Platform::Resources _dev { _env, _rm, _irq_dispatcher }; + Platform::Resources _dev { _env, _rm, _irq_dispatcher, + _config_aperture_size() }; Signal_handler
_system_sigh { _env.ep(), *this, &Main::_system_update }; @@ -2559,6 +2561,16 @@ struct Main : Irq_ack_handler, Gpu_reset_handler }); } + Number_of_bytes _config_aperture_size() const + { + auto aperture_size = Number_of_bytes(64ull << 20); + + if (_config_rom.valid()) + aperture_size = _config_rom.xml().attribute_value("max_framebuffer_memory", aperture_size); + + return aperture_size; + } + void _handle_config_update() { _config_rom.update(); @@ -2661,7 +2673,7 @@ struct Main : Irq_ack_handler, Gpu_reset_handler _dev.with_mmio([&](auto &mmio) { _dev.with_platform([&](auto &plat_con) { auto const base = mmio.base() + (mmio.size() / 2); - Igd::Ggtt(plat_con, mmio, base, Igd::GTT_RESERVED, 0, 0); + Igd::Ggtt(plat_con, mmio, base, _dev.gtt_reserved(), 0, 0); }); }, []() { error("reset failed"); diff --git a/repos/os/src/drivers/gpu/intel/platform_session.h b/repos/os/src/drivers/gpu/intel/platform_session.h index 5fd50aea25..3a84e4afe4 100644 --- a/repos/os/src/drivers/gpu/intel/platform_session.h +++ b/repos/os/src/drivers/gpu/intel/platform_session.h @@ -286,6 +286,7 @@ class Platform::Resources : Noncopyable Env & _env; Signal_context_capability const _irq_cap; + Platform::Connection _platform { _env }; Reconstructible _device { _platform }; Reconstructible _irq { *_device }; @@ -293,6 +294,8 @@ class Platform::Resources : Noncopyable Reconstructible > _gmadr { *_device, Platform::Device::Mmio<0>::Index(1) }; Reconstructible _gmadr_mem { _env.rm(), _gmadr->cap() }; + uint64_t const _aperture_reserved; + Region_map_client _rm_gttmm; Region_map_client _rm_gmadr; Range _range_gttmm; @@ -312,7 +315,7 @@ class Platform::Resources : Noncopyable size_t const gttm_half_size = mmio.size() / 2; off_t const gtt_offset = gttm_half_size; - if (gttm_half_size < GTT_RESERVED) { + if (gttm_half_size < gtt_reserved()) { Genode::error("GTTM size too small"); return; } @@ -324,25 +327,59 @@ class Platform::Resources : Noncopyable /* attach beginning of GTT */ _rm_gttmm.detach(gtt_offset); _rm_gttmm.attach_at(mmio.cap(), gtt_offset, - GTT_RESERVED, gtt_offset); + gtt_reserved(), gtt_offset); _rm_gmadr.detach(0ul); - _rm_gmadr.attach_at(gmadr.cap(), 0ul, APERTURE_RESERVED); + _rm_gmadr.attach_at(gmadr.cap(), 0ul, aperture_reserved()); }, []() { error("reinit failed"); }); } + Number_of_bytes _sanitized_aperture_size(Number_of_bytes memory) const + { + /* + * Ranges of global GTT (ggtt) are handed in page granularity (4k) + * to the platform client (intel display driver). + * 512 page table entries a 4k fit into one page, which adds up to + * 2M virtual address space. + */ + auto constexpr shift_2mb = 21ull; + auto constexpr MIN_MEMORY_FOR_MULTIPLEXER = 4ull << shift_2mb; + + /* align requests to 2M and enforce 2M as minimum */ + memory = memory & _align_mask(shift_2mb); + if (memory < (1ull << shift_2mb)) + memory = 1ull << shift_2mb; + + if (_gmadr->size() >= MIN_MEMORY_FOR_MULTIPLEXER) { + if (memory > _gmadr->size() - MIN_MEMORY_FOR_MULTIPLEXER) + memory = _gmadr->size() - MIN_MEMORY_FOR_MULTIPLEXER; + } else { + /* paranoia case, should never trigger */ + memory = _gmadr->size() / 2; + error("aperture smaller than ", MIN_MEMORY_FOR_MULTIPLEXER, + " will not work properly"); + } + + log("Maximum aperture size ", Number_of_bytes(_gmadr->size())); + log(" - available framebuffer memory for display driver: ", memory); + + return memory; + } + public: - Resources(Env &env, Rm_connection &rm, Signal_context_capability irq) + Resources(Env &env, Rm_connection &rm, Signal_context_capability irq, + Number_of_bytes const &aperture) : _env(env), _irq_cap(irq), + _aperture_reserved(_sanitized_aperture_size(aperture)), _rm_gttmm(rm.create(_mmio->size())), - _rm_gmadr(rm.create(Igd::APERTURE_RESERVED)), + _rm_gmadr(rm.create(aperture_reserved())), _range_gttmm(1ul << 30, _mmio->size()), - _range_gmadr(1ul << 29, _gmadr->size()) + _range_gmadr(1ul << 29, aperture_reserved()) { _irq->sigh(_irq_cap); @@ -350,7 +387,7 @@ class Platform::Resources : Noncopyable size_t const gttm_half_size = _mmio->size() / 2; off_t const gtt_offset = gttm_half_size; - if (gttm_half_size < Igd::GTT_RESERVED) { + if (gttm_half_size < gtt_reserved()) { Genode::error("GTTM size too small"); return; } @@ -359,9 +396,9 @@ class Platform::Resources : Noncopyable /* attach the rest of the GTT as dummy RAM */ auto const dummmy_gtt_ds = _env.ram().alloc(Igd::PAGE_SIZE); - auto remainder = gttm_half_size - Igd::GTT_RESERVED; + auto remainder = gttm_half_size - gtt_reserved(); - for (off_t offset = gtt_offset + Igd::GTT_RESERVED; + for (off_t offset = gtt_offset + gtt_reserved(); remainder > 0; offset += Igd::PAGE_SIZE, remainder -= Igd::PAGE_SIZE) { @@ -435,6 +472,17 @@ class Platform::Resources : Noncopyable _irq.destruct(); _device.destruct(); } + + /* + * Reserved aperture for platform service + */ + uint64_t aperture_reserved() const { return _aperture_reserved; } + + uint64_t gtt_reserved() const + { + /* reserved GTT for platform service, GTT entry is 8 byte */ + return (aperture_reserved() / Igd::PAGE_SIZE) * 8; + } }; diff --git a/repos/os/src/drivers/gpu/intel/types.h b/repos/os/src/drivers/gpu/intel/types.h index 1c2ec0b957..ed6283fb17 100644 --- a/repos/os/src/drivers/gpu/intel/types.h +++ b/repos/os/src/drivers/gpu/intel/types.h @@ -30,10 +30,6 @@ namespace Igd { enum { PAGE_SIZE = 4096, - /* reserved aperture for platform service */ - APERTURE_RESERVED = 64u<<20, - /* reserved GTT for platform service, GTT entry is 8 byte */ - GTT_RESERVED = (APERTURE_RESERVED/PAGE_SIZE) * 8, }; inline void wmb() { asm volatile ("sfence": : :"memory"); } diff --git a/repos/pc/run/intel_fb.run b/repos/pc/run/intel_fb.run index cdeeea9d19..c3e7271094 100644 --- a/repos/pc/run/intel_fb.run +++ b/repos/pc/run/intel_fb.run @@ -229,7 +229,7 @@ append_if $use_gpu config { - +