diff --git a/repos/os/src/drivers/gpu/intel/context.h b/repos/os/src/drivers/gpu/intel/context.h index 70c4a0b35c..35531bb0d8 100644 --- a/repos/os/src/drivers/gpu/intel/context.h +++ b/repos/os/src/drivers/gpu/intel/context.h @@ -1,11 +1,11 @@ /* - * \brief Broadwell logical ring context + * \brief Intel GPU logical ring context for Broadwell and newer * \author Josef Soentgen * \date 2017-03-15 */ /* - * Copyright (C) 2017 Genode Labs GmbH + * Copyright (C) 2017-2024 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -360,13 +360,12 @@ class Igd::Execlist_context : public Igd::Common_context_regs public: - Execlist_context(addr_t const base, - addr_t const ring_buffer_start, - size_t const ring_buffer_length, - uint32_t const immediate_header, - Generation const gen) - : - Common_context_regs(base) + Execlist_context(addr_t const base) : Common_context_regs(base) { } + + void setup(addr_t const ring_buffer_start, + size_t const ring_buffer_length, + uint32_t const immediate_header, + Generation const gen) { write(immediate_header); write_offset(RING_BASE); @@ -597,9 +596,9 @@ class Igd::Ppgtt_context : public Igd::Common_context_regs public: - Ppgtt_context(addr_t base, uint64_t plm4_addr) - : - Common_context_regs(base) + Ppgtt_context(addr_t const base) : Common_context_regs(base) { } + + void setup(uint64_t const plm4_addr) { write(0x11001011); write_offset(RING_BASE); @@ -843,27 +842,30 @@ class Igd::Rcs_context Pphardware_status_page _hw_status_page; Execlist_context _execlist_context; Ppgtt_context _ppgtt_context; - Engine_context _engine_context; - Ext_engine_context _ext_engine_context; - Urb_atomic_context _urb_atomic_context; + Engine_context _engine_context { }; + Ext_engine_context _ext_engine_context { }; + Urb_atomic_context _urb_atomic_context { }; public: - Rcs_context(addr_t const map_base, - addr_t const ring_buffer_start, - size_t const ring_buffer_length, - uint64_t const plm4_addr, - Generation const gen) + Rcs_context(addr_t const map_base) : - _hw_status_page(map_base), - _execlist_context((addr_t)(map_base + HW_STATUS_PAGE_SIZE), - ring_buffer_start, ring_buffer_length, - EXECLIST_CTX_IH, gen), - _ppgtt_context((addr_t)(map_base + HW_STATUS_PAGE_SIZE), plm4_addr), - _engine_context(), - _ext_engine_context(), - _urb_atomic_context() + _hw_status_page (map_base), + _execlist_context(map_base + HW_STATUS_PAGE_SIZE), + _ppgtt_context (map_base + HW_STATUS_PAGE_SIZE) + { } + + void setup(addr_t const ring_buffer_start, + size_t const ring_buffer_length, + uint64_t const plm4_addr, + Generation const gen) { + auto const map_base = _hw_status_page.base(); + + _execlist_context.setup(ring_buffer_start, ring_buffer_length, + EXECLIST_CTX_IH, gen); + _ppgtt_context.setup(plm4_addr); + if (false) Genode::log(__func__, ":", " map_base:", Genode::Hex(map_base), diff --git a/repos/os/src/drivers/gpu/intel/ggtt.h b/repos/os/src/drivers/gpu/intel/ggtt.h index 528375d7f4..816f43966d 100644 --- a/repos/os/src/drivers/gpu/intel/ggtt.h +++ b/repos/os/src/drivers/gpu/intel/ggtt.h @@ -39,16 +39,17 @@ class Igd::Ggtt struct Mapping { - Genode::Dataspace_capability cap { }; - Offset offset; - Igd::addr_t vaddr = 0; + Offset const offset; + Igd::addr_t const vsize; - enum { INVALID_OFFSET = ~0u - 1, }; + enum { INVALID_OFFSET = ~0u - 1 }; - Mapping() : offset(INVALID_OFFSET) { } + Mapping() : offset(INVALID_OFFSET), vsize(0) { } - Mapping(Genode::Dataspace_capability cap, Offset offset) - : cap(cap), offset(offset) { } + Mapping(Offset off_set, Igd::addr_t size) + : offset(off_set), vsize(size) { } + + bool invalid() const { return offset == INVALID_OFFSET; } virtual ~Mapping() { } }; diff --git a/repos/os/src/drivers/gpu/intel/main.cc b/repos/os/src/drivers/gpu/intel/main.cc index 099bc33d53..9584609542 100644 --- a/repos/os/src/drivers/gpu/intel/main.cc +++ b/repos/os/src/drivers/gpu/intel/main.cc @@ -269,9 +269,9 @@ struct Igd::Device if (!_ggtt.constructed()) return false; - fn(*_ggtt); - - return true; + return _resources.with_mmio([&](auto &mmio) { + fn(*_ggtt, mmio); + }); } __attribute__((warn_unused_result)) @@ -307,53 +307,31 @@ struct Igd::Device _pci_backend_alloc.free(cap); } - struct Ggtt_mmio_mapping : Ggtt::Mapping + Genode::Registry> _ggtt_mapping_registry { }; + + Ggtt::Mapping &map_dataspace_ggtt(Genode::Allocator &alloc, + Genode::Ram_dataspace_capability cap, + Ggtt::Offset offset) { - Region_map_client _rmc; + Genode::Registered *mem = nullptr; - Ggtt_mmio_mapping(Rm_connection & rm, - Dataspace_capability cap, - Ggtt::Offset offset, - size_t size) - : - _rmc(rm.create(size)) - { - _rmc.attach_at(cap, 0, size, offset * PAGE_SIZE); - Ggtt::Mapping::cap = _rmc.dataspace(); - Ggtt::Mapping::offset = offset; - } + if (!with_ggtt([&](auto &ggtt, auto &mmio) { + Genode::Dataspace_client client(cap); + addr_t const phys_addr = _pci_backend_alloc.dma_addr(cap); + size_t const size = client.size(); - virtual ~Ggtt_mmio_mapping() { } - }; + /* + * Create the mapping first and insert the entries afterwards + * so we do not have to rollback when the allocation fails. + */ + mem = new (&alloc) + Genode::Registered(_ggtt_mapping_registry, + offset, size); - Genode::Registry> _ggtt_mmio_mapping_registry { }; - - Ggtt_mmio_mapping const &map_dataspace_ggtt(Genode::Allocator &alloc, - Genode::Ram_dataspace_capability cap, - Ggtt::Offset offset) - { - Genode::Registered *mem = nullptr; - - if (!with_ggtt([&](auto &ggtt) { - if (!_resources.with_mmio_gmadr([&](auto &mmio, auto &gmadr) { - Genode::Dataspace_client client(cap); - addr_t const phys_addr = _pci_backend_alloc.dma_addr(cap); - size_t const size = client.size(); - - /* - * Create the mapping first and insert the entries afterwards - * so we do not have to rollback when the allocation fails. - */ - mem = new (&alloc) - Genode::Registered(_ggtt_mmio_mapping_registry, - _rm, gmadr.cap(), offset, size); - - for (size_t i = 0; i < size; i += PAGE_SIZE) { - addr_t const pa = phys_addr + i; - ggtt.insert_pte(mmio, pa, offset + (i / PAGE_SIZE)); - } - })) - error(__func__, " failed"); + for (size_t i = 0; i < size; i += PAGE_SIZE) { + addr_t const pa = phys_addr + i; + ggtt.insert_pte(mmio, pa, offset + (i / PAGE_SIZE)); + } })) throw Could_not_map_vram(); @@ -363,22 +341,12 @@ struct Igd::Device return *mem; } - void unmap_dataspace_ggtt(Genode::Allocator &alloc, Genode::Dataspace_capability cap) + void unmap_dataspace_ggtt(Genode::Allocator &alloc, Ggtt::Mapping &m) { - size_t const num = Genode::Dataspace_client(cap).size() / PAGE_SIZE; - - if (!with_ggtt([&](auto &ggtt) { - if (!_resources.with_mmio([&](auto &mmio) { - auto lookup_and_free = [&] (Ggtt_mmio_mapping &m) { - if (!(m.cap == cap)) { return; } - - ggtt.remove_pte_range(mmio, m.offset, num); - Genode::destroy(&alloc, &m); - }; - - _ggtt_mmio_mapping_registry.for_each(lookup_and_free); - })) - error(__func__, " with_mmio failed"); + if (!with_ggtt([&](auto &ggtt, auto &mmio) { + size_t const num = m.vsize / PAGE_SIZE; + ggtt.remove_pte_range(mmio, m.offset, num); + Genode::destroy(&alloc, &m); })) error(__func__, " failed"); } @@ -400,17 +368,11 @@ struct Igd::Device struct Execlist : Genode::Noncopyable { Igd::Context_descriptor _elem0; - Igd::Context_descriptor _elem1; + Igd::Context_descriptor _elem1 { }; - Igd::Ring_buffer _ring; - bool _scheduled; + bool _scheduled { }; - Execlist(uint32_t const id, addr_t const lrca, - addr_t const ring, size_t const ring_size) - : - _elem0(id, lrca), _elem1(), - _ring(ring, ring_size), _scheduled(false) - { } + Execlist(uint32_t const id, addr_t const lrca) : _elem0(id, lrca) { } Igd::Context_descriptor elem0() const { return _elem0; } Igd::Context_descriptor elem1() const { return _elem1; } @@ -418,28 +380,6 @@ struct Igd::Device void schedule(int port) { _scheduled = port; } int scheduled() const { return _scheduled; } - /************************* - ** Ring vram interface ** - *************************/ - - void ring_reset() { _ring.reset(); } - Ring_buffer::Index ring_tail() const { return _ring.tail(); } - Ring_buffer::Index ring_head() const { return _ring.head(); } - Ring_buffer::Index ring_append(Igd::Cmd_header cmd) { return _ring.append(cmd); } - - bool ring_avail(Ring_buffer::Index num) const { return _ring.avail(num); } - Ring_buffer::Index ring_max() const { return _ring.max(); } - void ring_reset_and_fill_zero() { _ring.reset_and_fill_zero(); } - void ring_update_head(Ring_buffer::Index head) { _ring.update_head(head); } - void ring_reset_to_head(Ring_buffer::Index head) { _ring.reset_to_head(head); } - - void ring_flush(Ring_buffer::Index from, Ring_buffer::Index to) - { - _ring.flush(from, to); - } - - void ring_dump(size_t limit, unsigned hw_tail, unsigned hw_head) const { _ring.dump(limit, hw_tail, hw_head); } - /********************* ** Debug interface ** *********************/ @@ -465,18 +405,20 @@ struct Igd::Device }; struct Mapping_guard { - Device &device; - Allocator &alloc; - Ggtt::Mapping const ↦ + Device &device; + Allocator &alloc; + Ggtt::Mapping ↦ - Mapping_guard(Device &device, Ggtt_map_memory &gmm, Allocator &alloc) + Mapping_guard(Device & device, + Ggtt_map_memory & gmm, + Allocator & alloc) : device(device), alloc(alloc), map(device.map_dataspace_ggtt(alloc, gmm.ram_ds.ds, gmm.offset)) { } - ~Mapping_guard() { device.unmap_dataspace_ggtt(alloc, map.cap); } + ~Mapping_guard() { device.unmap_dataspace_ggtt(alloc, map); } }; Device const &device; @@ -485,13 +427,6 @@ struct Igd::Device Ggtt::Offset const skip; Dataspace_guard const ram_ds; Mapping_guard const map; - Attached_dataspace const ram; - - addr_t vaddr() const - { - return reinterpret_cast(ram.local_addr()) - + (skip * PAGE_SIZE); - } Ggtt::Offset _offset(Ggtt::Offset const &pages) { @@ -505,10 +440,20 @@ struct Igd::Device return offset; } + void with_vaddr(auto const &fn) const + { + addr_t const offset = (map.map.offset + skip) * PAGE_SIZE; + + if (!device._resources.with_gmadr(offset, [&](auto const addr) { + fn(addr); + })) + error("Gmadr object unavailable"); + } + addr_t gmaddr() const { /* graphics memory address */ return (offset + skip) * PAGE_SIZE; } - Ggtt_map_memory(Region_map &rm, Allocator &alloc, Device &device, + Ggtt_map_memory(Allocator &alloc, Device &device, Ggtt::Offset const pages, Ggtt::Offset const skip_pages) : device(device), @@ -516,8 +461,7 @@ struct Igd::Device offset(_offset(pages)), skip(skip_pages), ram_ds(device, device._alloc_dataspace(pages * PAGE_SIZE)), - map(device, *this, alloc), - ram(rm, map.map.cap) + map(device, *this, alloc) { } }; @@ -534,17 +478,42 @@ struct Igd::Device Ppgtt_scratch ppgtt_scratch; Ppgtt *ppgtt { nullptr }; - Genode::Constructible context { }; - Genode::Constructible execlist { }; + Execlist execlist; + + Igd::Ring_buffer _ring { ring, ring_size() }; + + void with_context(auto const &fn) + { + ctx.with_vaddr([&](auto const vaddr) { + auto context = CONTEXT(vaddr); + + fn(context); + }); + } + + void with_context_ring(auto const &fn) + { + ctx.with_vaddr([&](auto const vaddr) { + auto context = CONTEXT(vaddr); + + fn(context, _ring); + }); + } + + void with_ring(auto const &fn) + { + fn(_ring); + } Engine(Igd::Device &device, uint32_t id, Allocator &alloc) : - ctx (device._env.rm(), alloc, device, CONTEXT::CONTEXT_PAGES, 1 /* omit GuC page */), - ring(device._env.rm(), alloc, device, CONTEXT::RING_PAGES, 0), + ctx (alloc, device, CONTEXT::CONTEXT_PAGES, 1 /* omit GuC page */), + ring(alloc, device, CONTEXT::RING_PAGES, 0), ppgtt_allocator(alloc, device._env.rm(), device._pci_backend_alloc), - ppgtt_scratch(device._pci_backend_alloc) + ppgtt_scratch(device._pci_backend_alloc), + execlist(id, ctx.gmaddr()) { /* PPGTT */ device._populate_scratch(ppgtt_scratch); @@ -552,7 +521,6 @@ struct Igd::Device ppgtt = new (ppgtt_allocator) Igd::Ppgtt(&ppgtt_scratch.pdp); try { - size_t const ring_size = RING_PAGES * PAGE_SIZE; /* get PML4 address */ addr_t const ppgtt_phys_addr = _ppgtt_phys_addr(ppgtt_allocator, @@ -560,11 +528,13 @@ struct Igd::Device addr_t const pml4 = ppgtt_phys_addr | 1; /* setup context */ - context.construct(ctx.vaddr(), ring.gmaddr(), ring_size, pml4, device.generation()); + with_context([&](auto &context) { + context.setup(ring.gmaddr(), ring_size(), pml4, + device.generation()); + }); - /* setup execlist */ - execlist.construct(id, ctx.gmaddr(), ring.vaddr(), ring_size); - execlist->ring_reset(); + /* initialize ring */ + _ring.reset(); } catch (...) { _destruct(); throw; @@ -577,9 +547,6 @@ struct Igd::Device { if (ppgtt) Genode::destroy(ppgtt_allocator, ppgtt); - - execlist.destruct(); - context.destruct(); } size_t ring_size() const { return RING_PAGES * PAGE_SIZE; } @@ -707,14 +674,23 @@ struct Igd::Device } bool setup_ring_vram(Gpu::addr_t const vram_addr) + { + bool ok = false; + + rcs.with_ring([&](auto &ring) { + ok = _setup_ring_vram(vram_addr, ring); + }); + + return ok; + } + + bool _setup_ring_vram(Gpu::addr_t const vram_addr, auto &ring) { _current_seqno++; unsigned generation = _device.generation().value; - Execlist &el = *rcs.execlist; - - Ring_buffer::Index advance = 0; + auto advance = 0; bool dc_flush_wa = _device.match(Device_info::Platform::KABYLAKE, Device_info::Stepping::A0, @@ -725,11 +701,11 @@ struct Igd::Device + ((generation == 8) ? 20 : 22) /* epilog + w/a */ + (dc_flush_wa ? 12 : 0); - if (!el.ring_avail(need)) - el.ring_reset_and_fill_zero(); + if (!ring.avail(need)) + ring.reset_and_fill_zero(); /* save old tail */ - Ring_buffer::Index const tail = el.ring_tail(); + auto const tail = ring.tail(); /* * IHD-OS-BDW-Vol 7-11.15 p. 18 ff. @@ -748,7 +724,7 @@ struct Igd::Device cmd[0] = pc.value; for (size_t i = 0; i < CMD_NUM; i++) { - advance += el.ring_append(cmd[i]); + advance += ring.append(cmd[i]); } } @@ -760,7 +736,7 @@ struct Igd::Device cmd[1] = Igd::Pipe_control::DC_FLUSH_ENABLE; for (size_t i = 0; i < CMD_NUM; i++) { - advance += el.ring_append(cmd[i]); + advance += ring.append(cmd[i]); } } @@ -790,7 +766,7 @@ struct Igd::Device cmd[2] = 0x34 * 4; for (size_t i = 0; i < CMD_NUM; i++) { - advance += el.ring_append(cmd[i]); + advance += ring.append(cmd[i]); } } @@ -802,7 +778,7 @@ struct Igd::Device cmd[1] = Igd::Pipe_control::CS_STALL; for (size_t i = 0; i < CMD_NUM; i++) { - advance += el.ring_append(cmd[i]); + advance += ring.append(cmd[i]); } } @@ -823,7 +799,7 @@ struct Igd::Device cmd[3] = (vram_addr >> 32) & 0xffff; for (size_t i = 0; i < CMD_NUM; i++) { - advance += el.ring_append(cmd[i]); + advance += ring.append(cmd[i]); } } @@ -846,7 +822,7 @@ struct Igd::Device cmd[5] = Mi_noop().value; for (size_t i = 0; i < CMD_NUM; i++) { - advance += el.ring_append(cmd[i]); + advance += ring.append(cmd[i]); } } @@ -864,7 +840,7 @@ struct Igd::Device cmd[1] = tmp; for (size_t i = 0; i < CMD_NUM; i++) { - advance += el.ring_append(cmd[i]); + advance += ring.append(cmd[i]); } } @@ -890,7 +866,7 @@ struct Igd::Device cmd[5] = _current_seqno >> 32; for (size_t i = 0; i < CMD_NUM; i++) { - advance += el.ring_append(cmd[i]); + advance += ring.append(cmd[i]); } } @@ -917,7 +893,7 @@ struct Igd::Device cmd[5] = generation < 12 ? Mi_noop().value : 0; for (size_t i = 0; i < CMD_NUM; i++) { - advance += el.ring_append(cmd[i]); + advance += ring.append(cmd[i]); } } @@ -930,7 +906,7 @@ struct Igd::Device cmd[1] = ui.value; for (size_t i = 0; i < CMD_NUM; i++) { - advance += el.ring_append(cmd[i]); + advance += ring.append(cmd[i]); } } @@ -950,7 +926,7 @@ struct Igd::Device cmd[1] = Mi_noop().value; for (size_t i = 0; i < CMD_NUM; i++) { - advance += el.ring_append(cmd[i]); + advance += ring.append(cmd[i]); } } @@ -961,10 +937,12 @@ struct Igd::Device return false; } - el.ring_flush(tail, tail + advance); + ring.flush(tail, tail + advance); /* tail_offset must be specified in qword */ - rcs.context->tail_offset((offset % (rcs.ring_size())) / 8); + rcs.with_context([&](auto &context) { + context.tail_offset((offset % (rcs.ring_size())) / 8); + }); return true; } @@ -996,7 +974,7 @@ struct Igd::Device void _submit_execlist(Igd::Mmio &mmio, Engine &engine) { - Execlist &el = *engine.execlist; + Execlist &el = engine.execlist; int const port = mmio.read(); @@ -1043,7 +1021,7 @@ struct Igd::Device if (mmio.read() == 0) return; - Execlist &el = *engine.execlist; + Execlist &el = engine.execlist; mmio.write(el.elem0().low(), 0); mmio.write(el.elem0().high(), 1); @@ -1104,20 +1082,19 @@ struct Igd::Device /** * \return true, if Vgpu is done and has not further work */ - bool _notify_complete(Vgpu *gpu) + bool _notify_complete(Vgpu &gpu) { - if (!gpu) { return true; } + uint64_t const curr_seqno = gpu.current_seqno(); + uint64_t const comp_seqno = gpu.completed_seqno(); - uint64_t const curr_seqno = gpu->current_seqno(); - uint64_t const comp_seqno = gpu->completed_seqno(); - - Execlist &el = *gpu->rcs.execlist; - el.ring_update_head(gpu->rcs.context->head_offset()); + gpu.rcs.with_context_ring([&](auto &context, auto &ring) { + ring.update_head(context.head_offset()); + }); if (curr_seqno != comp_seqno) return false; - Genode::Signal_transmitter(gpu->completion_sigh()).submit(); + Genode::Signal_transmitter(gpu.completion_sigh()).submit(); return true; } @@ -1158,15 +1135,16 @@ struct Igd::Device { /* signal completion of last job to vgpu */ vgpu.mark_completed(); - _notify_complete(&vgpu); + _notify_complete(vgpu); - /* offset of head in ring context */ - size_t head_offset = vgpu.rcs.context->head_offset(); - /* set head = tail in ring and ring context */ - Execlist &el = *vgpu.rcs.execlist; - el.ring_reset_to_head(head_offset); - /* set tail in context in qwords */ - vgpu.rcs.context->tail_offset((head_offset % (vgpu.rcs.ring_size())) / 8); + vgpu.rcs.with_context_ring([&](auto &context, auto &ring) { + /* offset of head in ring context */ + size_t head_offset = context.head_offset(); + /* set head = tail in ring and ring context */ + ring.reset_to_head(head_offset); + /* set tail in context in qwords */ + context.tail_offset((head_offset % (vgpu.rcs.ring_size())) / 8); + }); } void _handle_watchdog_timeout() @@ -1183,12 +1161,14 @@ struct Igd::Device mmio.fault_dump(); mmio.execlist_status_dump(); - _active_vgpu->rcs.context->dump(); - _hw_status_page->dump(); - Execlist &el = *_active_vgpu->rcs.execlist; - el.ring_update_head(_active_vgpu->rcs.context->head_offset()); - el.ring_dump(4096, _active_vgpu->rcs.context->tail_offset() * 2, - _active_vgpu->rcs.context->head_offset()); + _active_vgpu->rcs.with_context_ring([&](auto &context, auto &ring) { + context.dump(); + _hw_status_page->dump(); + + ring.update_head(context.head_offset()); + ring.dump(4096, context.tail_offset() * 2, + context.head_offset()); + }); } @@ -1265,9 +1245,13 @@ struct Igd::Device /* setup global hardware status page */ if (!_hw_status_ctx.constructed()) - _hw_status_ctx.construct(_env.rm(), _md_alloc, *this, 1, 0); - if (!_hw_status_page.constructed()) - _hw_status_page.construct(_hw_status_ctx->vaddr()); + _hw_status_ctx.construct(_md_alloc, *this, 1, 0); + if (!_hw_status_page.constructed()) { + /* global hw_status_ctx becomes never invalid up to now, so using vaddr is ok */ + _hw_status_ctx->with_vaddr([&](auto const vaddr) { + _hw_status_page.construct(vaddr); + }); + } Mmio::HWS_PGA_RCSUNIT::access_t const addr = _hw_status_ctx->gmaddr(); mmio.write_post(addr); @@ -1629,48 +1613,6 @@ struct Igd::Device _pci_backend_alloc.free(Genode::static_cap_cast(cap)); } - /** - * Map DMA vram in the GGTT - * - * \param guard resource allocator and guard - * \param cap DMA vram capability - * \param aperture true if mapping should be accessible by CPU - * - * \return GGTT mapping - * - * \throw Could_not_map_vram - */ - Ggtt::Mapping const &map_vram(Genode::Allocator &guard, - Genode::Ram_dataspace_capability cap, - bool aperture) - { - if (aperture == false) { - error("GGTT mapping outside aperture"); - throw Could_not_map_vram(); - } - - if (!_ggtt.constructed()) { - error("GGTT mapping failed"); - throw Could_not_map_vram(); - } - - 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); - return map_dataspace_ggtt(guard, cap, offset); - } - - /** - * Unmap DMA vram from GGTT - * - * \param guard resource allocator and guard - * \param mapping GGTT mapping - */ - void unmap_vram(Genode::Allocator &guard, Ggtt::Mapping mapping) - { - unmap_dataspace_ggtt(guard, mapping.cap); - } - /** * Set tiling mode for GGTT region * @@ -1742,7 +1684,7 @@ struct Igd::Device _unschedule_current_vgpu(); if (notify_gpu) { - if (!_notify_complete(notify_gpu)) { + if (!_notify_complete(*notify_gpu)) { _vgpu_list.enqueue(*notify_gpu); } } @@ -2027,8 +1969,8 @@ class Gpu::Session_component : public Genode::Session_object */ if (vram.owner(_owner.cap) == false) return false; - if (vram.map.offset != Igd::Ggtt::Mapping::INVALID_OFFSET) { - _device.unmap_vram(_heap, vram.map); + if (!vram.map.invalid()) { + _device.unmap_dataspace_ggtt(_heap, vram.map); } if (vram.fenced != Vram::INVALID_FENCE) { @@ -2187,7 +2129,7 @@ class Gpu::Session_component : public Genode::Session_object if (vram.owner(cap()) == false) return false; - if (vram.map.offset != Igd::Ggtt::Mapping::INVALID_OFFSET) { + if (!vram.map.invalid()) { Genode::error("cannot free mapped vram"); /* XXX throw */ return false; @@ -2342,7 +2284,7 @@ class Gpu::Session_component : public Genode::Session_object Vram *v = nullptr; auto lookup = [&] (Vram &vram) { - if (!vram.map.cap.valid() || !vram.owner(cap())) { return false; } + if (vram.map.invalid() || !vram.owner(cap())) { return false; } v = &vram; return false; }; @@ -2435,7 +2377,6 @@ class Gpu::Root : public Gpu::Root_component _device->reset(mmio); })) Genode::warning("vGPU active, reset of device failed"); - } else { /* remove from scheduled list */ s->vgpu_unschedule(); diff --git a/repos/os/src/drivers/gpu/intel/platform_session.h b/repos/os/src/drivers/gpu/intel/platform_session.h index 8f2a396e4c..69b7ba518d 100644 --- a/repos/os/src/drivers/gpu/intel/platform_session.h +++ b/repos/os/src/drivers/gpu/intel/platform_session.h @@ -286,11 +286,13 @@ class Platform::Resources : Noncopyable Env & _env; Signal_context_capability const _irq_cap; - Platform::Connection _platform { _env }; - Reconstructible _device { _platform }; - Reconstructible _irq { *_device }; - Reconstructible _mmio { *_device, _env }; - Reconstructible _gmadr { *_device, Platform::Device::Mmio::Index(1) }; + Platform::Connection _platform { _env }; + + Reconstructible _device { _platform }; + Reconstructible _irq { *_device }; + Reconstructible _mmio { *_device, _env }; + Reconstructible _gmadr { *_device, Platform::Device::Mmio::Index(1) }; + Reconstructible _gmadr_mem { _env.rm(), _gmadr->cap() }; Region_map_client _rm_gttmm; Region_map_client _rm_gmadr; @@ -379,6 +381,19 @@ class Platform::Resources : Noncopyable return true; } + __attribute__((warn_unused_result)) + bool with_gmadr(auto const offset, auto const &fn) + { + if (!_gmadr_mem.constructed()) + return false; + + auto const addr = reinterpret_cast(_gmadr_mem->local_addr()) + + offset; + fn(addr); + + return true; + } + __attribute__((warn_unused_result)) bool with_irq(auto const &fn) { diff --git a/repos/os/src/drivers/gpu/intel/ring_buffer.h b/repos/os/src/drivers/gpu/intel/ring_buffer.h index 344018ebbc..bdd59eaee5 100644 --- a/repos/os/src/drivers/gpu/intel/ring_buffer.h +++ b/repos/os/src/drivers/gpu/intel/ring_buffer.h @@ -1,11 +1,11 @@ /* - * \brief Broadwell ring buffer + * \brief Ring buffer for Broadwell and newer * \author Josef Soentgen * \date 2017-03-15 */ /* - * Copyright (C) 2017 Genode Labs GmbH + * Copyright (C) 2017-2024 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -24,12 +24,13 @@ namespace Igd { - class Ring_buffer; + template class Ring_buffer; } /* */ +template class Igd::Ring_buffer { public: @@ -38,30 +39,31 @@ class Igd::Ring_buffer private: - uint32_t *_dwords; - Index _max; - Index _tail; - Index _head; + MEMORY & _memory; + Index const _max; + Index _tail { }; + Index _head { }; + + void with_dwords(auto const &fn) const { + _memory.with_vaddr([&](auto vaddr) { fn((uint32_t *)vaddr); }); } + + void with_dwords(auto const &fn) { + _memory.with_vaddr([&](auto vaddr) { fn((uint32_t *)vaddr); }); } public: - Ring_buffer(addr_t base, - size_t length) - : - _dwords((uint32_t*)base), _max(length / sizeof (uint32_t)), - _tail(0), _head(0) - { - /* initial clear */ - Genode::memset(_dwords, 0, length); - } + Ring_buffer(MEMORY & memory, size_t const size) + : _memory(memory), _max(size / sizeof (uint32_t)) { } /** * Clear ring buffer and reset tail */ void reset() { - Genode::memset(_dwords, 0, _max * sizeof(uint32_t)); - _tail = 0; + with_dwords([&](auto dwords) { + Genode::memset(dwords, 0, _max * sizeof(uint32_t)); + _tail = 0; + }); } /** @@ -69,9 +71,11 @@ class Igd::Ring_buffer */ void reset_and_fill_zero() { - Genode::size_t const bytes = (_max - _tail) * sizeof(uint32_t); - Genode::memset(_dwords + _tail, 0, bytes); - _tail = 0; + with_dwords([&](auto dwords) { + auto const bytes = (_max - _tail) * sizeof(uint32_t); + Genode::memset(dwords + _tail, 0, bytes); + _tail = 0; + }); } /** @@ -118,19 +122,21 @@ class Igd::Ring_buffer if (index < _tail) { throw -1; } if (index > _max) { throw -2; } - _dwords[index] = cmd.value; - _tail++; + with_dwords([&](auto dwords) { + dwords[index] = cmd.value; + _tail++; - if (_tail >= _max) { - Genode::warning("ring buffer wrapped ", - "_tail: ", _tail, " ", "_max: ", _max); - _tail = 0; - } + if (_tail >= _max) { + Genode::warning("ring buffer wrapped ", + "_tail: ", _tail, " ", "_max: ", _max); + _tail = 0; + } - if (_tail == _head) { - Genode::error("tail: ", Genode::Hex(_tail), " == head: ", - Genode::Hex(_head), " in ring buffer"); - } + if (_tail == _head) { + Genode::error("tail: ", Genode::Hex(_tail), " == head: ", + Genode::Hex(_head), " in ring buffer"); + } + }); return 1; } @@ -184,11 +190,13 @@ class Igd::Ring_buffer */ void flush(Index from, Index to) const { - uint32_t *start = _dwords + from; - for (Index i = 0; i < (to - from); i++) { - uint32_t *addr = start++; - Utils::clflush(addr); - } + with_dwords([&](auto dwords) { + uint32_t *start = dwords + from; + for (Index i = 0; i < (to - from); i++) { + uint32_t *addr = start++; + Utils::clflush(addr); + } + }); } /********************* @@ -199,21 +207,24 @@ class Igd::Ring_buffer { using namespace Genode; - size_t const max = dw_limit ? dw_limit : _max; + with_dwords([&](auto dwords) { + size_t const max = dw_limit ? dw_limit : _max; - log("Ring_buffer: ", Hex(*_dwords), " max: ", _max, " (limit: ", max, ")", - " hardware read: tail=", Genode::Hex(hw_tail), - " head=", Genode::Hex(hw_head)); + log("Ring_buffer: ", Hex(*dwords), + " max: ", _max, " (limit: ", max, ")", + " hardware read: tail=", Genode::Hex(hw_tail), + " head=", Genode::Hex(hw_head)); - for (size_t i = 0; i < max; i++) { - log(Hex(i*4, Hex::PREFIX, Hex::PAD), " ", - Hex(_dwords[i], Hex::PREFIX, Hex::PAD), - i == _tail ? " T " : " ", - i == _head ? " H " : " ", - i == hw_tail ? " T_HW " : " ", - i == hw_head ? " H_HW " : " " - ); - } + for (size_t i = 0; i < max; i++) { + log(Hex(i*4, Hex::PREFIX, Hex::PAD), " ", + Hex(dwords[i], Hex::PREFIX, Hex::PAD), + i == _tail ? " T " : " ", + i == _head ? " H " : " ", + i == hw_tail ? " T_HW " : " ", + i == hw_head ? " H_HW " : " " + ); + } + }); } };