diff --git a/repos/os/src/drivers/gpu/intel/main.cc b/repos/os/src/drivers/gpu/intel/main.cc index 9a4397d1e9..1947d2d16a 100644 --- a/repos/os/src/drivers/gpu/intel/main.cc +++ b/repos/os/src/drivers/gpu/intel/main.cc @@ -22,12 +22,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -72,7 +72,7 @@ struct Igd::Device struct Unsupported_device : Genode::Exception { }; struct Out_of_caps : Genode::Exception { }; struct Out_of_ram : Genode::Exception { }; - struct Could_not_map_buffer : Genode::Exception { }; + struct Could_not_map_vram : Genode::Exception { }; enum { WATCHDOG_TIMEOUT = 1*1000*1000, }; @@ -112,7 +112,7 @@ struct Igd::Device [&] () { if (_env.pd().avail_caps().value < UPGRADE_CAPS) { - warning("alloc dma buffer: out if caps"); + warning("alloc dma vram: out if caps"); throw Gpu::Session::Out_of_caps(); } @@ -123,7 +123,7 @@ struct Igd::Device [&] () { if (_env.pd().avail_ram().value < size) { - warning("alloc dma buffer: out of ram"); + warning("alloc dma vram: out of ram"); throw Gpu::Session::Out_of_ram(); } _pci.upgrade_ram(size); @@ -379,9 +379,9 @@ struct Igd::Device void schedule(int port) { _scheduled = port; } int scheduled() const { return _scheduled; } - /*************************** - ** Ring buffer interface ** - ***************************/ + /************************* + ** Ring vram interface ** + *************************/ void ring_reset() { _ring.reset(); } Ring_buffer::Index ring_tail() const { return _ring.tail(); } @@ -652,7 +652,7 @@ struct Igd::Device Gpu::Sequence_number { .value = _device.seqno() }; } - bool setup_ring_buffer(Gpu::addr_t const buffer_addr) + bool setup_ring_vram(Gpu::addr_t const vram_addr) { _current_seqno++; @@ -664,7 +664,7 @@ struct Igd::Device Device_info::Stepping::A0, Device_info::Stepping::B0); - size_t const need = 4 /* batchbuffer cmd */ + 6 /* prolog */ + size_t const need = 4 /* batchvram cmd */ + 6 /* prolog */ + ((_device.generation().value == 9) ? 6 : 0) + ((_device.generation().value == 8) ? 20 : 22) /* epilog + w/a */ + (dc_flush_wa ? 12 : 0); @@ -753,7 +753,7 @@ struct Igd::Device /* * gen8_emit_bb_start_noarb, gen8 and render engine * - * batch-buffer commands + * batch-vram commands */ if (_device.generation().value == 8) { @@ -763,8 +763,8 @@ struct Igd::Device cmd[0] = Mi_arb_on_off(false).value; cmd[1] = mi.value; - cmd[2] = buffer_addr & 0xffffffff; - cmd[3] = (buffer_addr >> 32) & 0xffff; + cmd[2] = vram_addr & 0xffffffff; + cmd[3] = (vram_addr >> 32) & 0xffff; for (size_t i = 0; i < CMD_NUM; i++) { advance += el.ring_append(cmd[i]); @@ -774,7 +774,7 @@ struct Igd::Device /* * gen8_emit_bb_start, gen9 * - * batch-buffer commands + * batch-vram commands */ if (_device.generation().value >= 9) { @@ -784,8 +784,8 @@ struct Igd::Device cmd[0] = Mi_arb_on_off(true).value; cmd[1] = mi.value; - cmd[2] = buffer_addr & 0xffffffff; - cmd[3] = (buffer_addr >> 32) & 0xffff; + cmd[2] = vram_addr & 0xffffffff; + cmd[3] = (vram_addr >> 32) & 0xffff; cmd[4] = Mi_arb_on_off(false).value; cmd[5] = Mi_noop().value; @@ -1370,21 +1370,21 @@ struct Igd::Device return result; } - /********************* - ** Buffer handling ** - *********************/ + /******************* + ** Vram handling ** + *******************/ /** - * Allocate DMA buffer + * Allocate DMA vram * * \param guard resource allocator and guard - * \param size size of the DMA buffer + * \param size size of the DMA vram * - * \return DMA buffer capability + * \return DMA vram capability * * \throw Out_of_memory */ - Genode::Ram_dataspace_capability alloc_buffer(Allocator &, + Genode::Ram_dataspace_capability alloc_vram(Allocator &, size_t const size) { return _pci_backend_alloc.alloc(size); @@ -1392,7 +1392,7 @@ struct Igd::Device /** - * Get physical address for DMA buffer + * Get physical address for DMA vram * * \param ds_cap ram dataspace capability * @@ -1404,12 +1404,12 @@ struct Igd::Device } /** - * Free DMA buffer + * Free DMA vram * * \param guard resource allocator and guard - * \param cap DMA buffer capability + * \param cap DMA vram capability */ - void free_buffer(Allocator &, + void free_vram(Allocator &, Dataspace_capability const cap) { if (!cap.valid()) { return; } @@ -1418,23 +1418,23 @@ struct Igd::Device } /** - * Map DMA buffer in the GGTT + * Map DMA vram in the GGTT * * \param guard resource allocator and guard - * \param cap DMA buffer capability + * \param cap DMA vram capability * \param aperture true if mapping should be accessible by CPU * * \return GGTT mapping * - * \throw Could_not_map_buffer + * \throw Could_not_map_vram */ - Ggtt::Mapping const &map_buffer(Genode::Allocator &guard, + 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_buffer(); + throw Could_not_map_vram(); } size_t const size = Genode::Dataspace_client(cap).size(); @@ -1444,12 +1444,12 @@ struct Igd::Device } /** - * Unmap DMA buffer from GGTT + * Unmap DMA vram from GGTT * * \param guard resource allocator and guard * \param mapping GGTT mapping */ - void unmap_buffer(Genode::Allocator &guard, Ggtt::Mapping mapping) + void unmap_vram(Genode::Allocator &guard, Ggtt::Mapping mapping) { unmap_dataspace_ggtt(guard, mapping.cap); } @@ -1561,7 +1561,7 @@ namespace Gpu { } -struct Gpu::Buffer : Genode::Interface +struct Gpu::Vram : Genode::Interface { GENODE_RPC_INTERFACE(); }; @@ -1637,9 +1637,9 @@ class Gpu::Session_component : public Genode::Session_object Resource_guard _resource_guard { _cap_quota_guard(), _ram_quota_guard() }; /* - * Buffer managed by session ep + * Vram managed by session ep */ - struct Buffer : Rpc_object + struct Vram : Rpc_object { Ram_dataspace_capability ds_cap; Session_capability owner_cap; @@ -1655,8 +1655,8 @@ class Gpu::Session_component : public Genode::Session_object bool caps_used { false }; size_t ram_used { 0 }; - Buffer(Ram_dataspace_capability ds_cap, Genode::addr_t phys_addr, - Session_capability owner_cap) + Vram(Ram_dataspace_capability ds_cap, Genode::addr_t phys_addr, + Session_capability owner_cap) : ds_cap { ds_cap }, owner_cap { owner_cap }, phys_addr { phys_addr } @@ -1672,75 +1672,95 @@ class Gpu::Session_component : public Genode::Session_object }; /* - * Buffer session/gpu-context local buffer + * Vram session/gpu-context local vram */ - struct Buffer_local + struct Vram_local { - using Id_space = Genode::Id_space; + /* keep track of mappings of different offsets */ + struct Mapping : Dictionary::Element + { + addr_t ppgtt_va { 0 }; + size_t ppgtt_va_size { 0 }; + + Mapping(Dictionary &dict, off_t offset, + addr_t ppgtt_va, size_t ppgtt_va_size) + : + Dictionary::Element(dict, offset), + ppgtt_va(ppgtt_va), ppgtt_va_size(ppgtt_va_size) + { } + }; + + using Id_space = Genode::Id_space; + + Vram_capability const vram_cap; + size_t size; + Id_space::Element const elem; + Dictionary mappings { }; - Buffer_capability const buffer_cap; - size_t size; - Id_space::Element const elem; addr_t ppgtt_va { 0 }; bool ppgtt_va_valid { false }; - Buffer_local(Buffer_capability buffer_cap, size_t size, - Id_space &space, Buffer_id id) - : buffer_cap(buffer_cap), size(size), + Vram_local(Vram_capability vram_cap, size_t size, + Id_space &space, Vram_id id) + : vram_cap(vram_cap), size(size), elem(*this, space, Id_space::Id { .value = id.value }) { } }; - Id_space _buffer_space { }; + Id_space _vram_space { }; template - void _apply_buffer(Buffer_local &buffer_local, FN const &fn) + void _apply_vram(Vram_local &vram_local, FN const &fn) { - Buffer *b = nullptr; - bool free = _env.ep().rpc_ep().apply(buffer_local.buffer_cap, [&] (Buffer *buffer) { - if (buffer) { - b = buffer; - return fn(*buffer); + Vram *v = nullptr; + bool free = _env.ep().rpc_ep().apply(vram_local.vram_cap, [&] (Vram *vram) { + if (vram) { + v = vram; + return fn(*vram); } return false; }); - if (b && free) - destroy(&_heap, b); + if (v && free) + destroy(&_heap, v); } - bool _buffer_valid(Buffer_capability buffer_cap) + bool _vram_valid(Vram_capability vram_cap) { bool valid = false; - _env.ep().rpc_ep().apply(buffer_cap, [&] (Buffer *buffer) { - if (buffer) valid = true; + _env.ep().rpc_ep().apply(vram_cap, [&] (Vram *vram) { + if (vram) valid = true; }); return valid; } template - void _apply_buffer_local(Gpu::Buffer_id id, FN const &fn) + void _apply_vram_local(Gpu::Vram_id id, FN const &fn) { - Buffer_local::Id_space::Id local_id { .value = id.value }; + Vram_local::Id_space::Id local_id { .value = id.value }; try { - _buffer_space.apply(local_id, [&] (Buffer_local &buffer) { - fn(buffer); + _vram_space.apply(local_id, [&] (Vram_local &vram) { + fn(vram); }); - } catch (Buffer_local::Id_space::Unknown_id) { + } catch (Vram_local::Id_space::Unknown_id) { error("Unknown id: ", id.value); } } Genode::uint64_t seqno { 0 }; - void _free_local_buffer(Buffer_local &buffer_local) + void _free_local_vram(Vram_local &vram_local) { - if (buffer_local.ppgtt_va_valid) { - _vgpu.rcs_unmap_ppgtt(buffer_local.ppgtt_va, buffer_local.size); - } + vram_local.mappings.for_each([&] (Vram_local::Mapping const &mapping) { + _vgpu.rcs_unmap_ppgtt(mapping.ppgtt_va, mapping.ppgtt_va_size); + }); - destroy(&_heap, &buffer_local); + while (vram_local.mappings.with_any_element([&] (Vram_local::Mapping &mapping) { + destroy(_heap, &mapping); + })) { } + + destroy(&_heap, &vram_local); } public: @@ -1772,31 +1792,31 @@ class Gpu::Session_component : public Genode::Session_object ~Session_component() { - auto lookup_and_free = [&] (Buffer_local &buffer_local) { + auto lookup_and_free = [&] (Vram_local &vram_local) { - _apply_buffer(buffer_local, [&](Buffer &buffer) { + _apply_vram(vram_local, [&](Vram &vram) { - if (buffer.owner(_session_cap) == false) return false; + if (vram.owner(_session_cap) == false) return false; - if (buffer.map.offset != Igd::Ggtt::Mapping::INVALID_OFFSET) { - _device.unmap_buffer(_heap, buffer.map); + if (vram.map.offset != Igd::Ggtt::Mapping::INVALID_OFFSET) { + _device.unmap_vram(_heap, vram.map); } - if (buffer.fenced != Buffer::INVALID_FENCE) { - _device.clear_tiling(buffer.fenced); + if (vram.fenced != Vram::INVALID_FENCE) { + _device.clear_tiling(vram.fenced); _vgpu.active_fences--; } - _env.ep().dissolve(buffer); - _device.free_buffer(_heap, buffer.ds_cap); + _env.ep().dissolve(vram); + _device.free_vram(_heap, vram.ds_cap); return true; }); - _free_local_buffer(buffer_local); + _free_local_vram(vram_local); }; - while(_buffer_space.apply_any( - [&] (Buffer_local &buffer_local) { lookup_and_free(buffer_local); })); + while(_vram_space.apply_any( + [&] (Vram_local &vram_local) { lookup_and_free(vram_local); })); } /********************************* @@ -1831,25 +1851,31 @@ class Gpu::Session_component : public Genode::Session_object return _vgpu.info_dataspace(); } - Gpu::Sequence_number exec_buffer(Buffer_id id, - Genode::size_t) override + Gpu::Sequence_number execute(Vram_id id, off_t offset) override { bool found = false; - _apply_buffer_local(id, [&] (Buffer_local &buffer_local) { + _apply_vram_local(id, [&] (Vram_local &vram_local) { - if (_buffer_valid(buffer_local.buffer_cap) == false) { - _free_local_buffer(buffer_local); + if (_vram_valid(vram_local.vram_cap) == false) { + _free_local_vram(vram_local); return; } - if (!buffer_local.ppgtt_va_valid) { - Genode::error("Invalid execbuffer"); + addr_t ppgtt_va { 0 }; + + bool ppgtt_va_valid = vram_local.mappings.with_element(offset, + [&] (Vram_local::Mapping const &mapping) { + ppgtt_va = mapping.ppgtt_va; return true; }, + []() { return false; }); + + if (!ppgtt_va_valid) { + Genode::error("Invalid execvram"); Genode::Signal_transmitter(_vgpu.completion_sigh()).submit(); throw Gpu::Session::Invalid_state(); } - found = _vgpu.setup_ring_buffer(buffer_local.ppgtt_va); + found = _vgpu.setup_ring_vram(ppgtt_va); }); if (!found) @@ -1869,8 +1895,8 @@ class Gpu::Session_component : public Genode::Session_object _vgpu.completion_sigh(sigh); } - Genode::Dataspace_capability alloc_buffer(Gpu::Buffer_id id, - Genode::size_t size) override + Genode::Dataspace_capability alloc_vram(Gpu::Vram_id id, + Genode::size_t size) override { /* roundup to next page size */ size = align_addr(size, 12); @@ -1884,80 +1910,80 @@ class Gpu::Session_component : public Genode::Session_object size_t caps_before = _env.pd().avail_caps().value; size_t ram_before = _env.pd().avail_ram().value; - Ram_dataspace_capability ds_cap = _device.alloc_buffer(_heap, size); + Ram_dataspace_capability ds_cap = _device.alloc_vram(_heap, size); addr_t phys_addr = _device.dma_addr(ds_cap); - Buffer *buffer = new (&_heap) Buffer(ds_cap, phys_addr, _session_cap); - _env.ep().manage(*buffer); + Vram *vram = new (&_heap) Vram(ds_cap, phys_addr, _session_cap); + _env.ep().manage(*vram); try { - new (&_heap) Buffer_local(buffer->cap(), size, _buffer_space, id); - } catch (Id_space::Conflicting_id) { - _env.ep().dissolve(*buffer); - destroy(&_heap, buffer); - _device.free_buffer(_heap, ds_cap); + new (&_heap) Vram_local(vram->cap(), size, _vram_space, id); + } catch (Id_space::Conflicting_id) { + _env.ep().dissolve(*vram); + destroy(&_heap, vram); + _device.free_vram(_heap, ds_cap); return Dataspace_capability(); } size_t caps_after = _env.pd().avail_caps().value; size_t ram_after = _env.pd().avail_ram().value; - /* limit to buffer size for replenish */ - buffer->ram_used = min(ram_before > ram_after ? ram_before - ram_after : 0, size); - buffer->caps_used = caps_before > caps_after ? true : false; + /* limit to vram size for replenish */ + vram->ram_used = min(ram_before > ram_after ? ram_before - ram_after : 0, size); + vram->caps_used = caps_before > caps_after ? true : false; _resource_guard.withdraw(caps_before, caps_after, ram_before, ram_after); return ds_cap; } - void free_buffer(Gpu::Buffer_id id) override + void free_vram(Gpu::Vram_id id) override { - auto lookup_and_free = [&] (Buffer_local &buffer_local) { + auto lookup_and_free = [&] (Vram_local &vram_local) { - _apply_buffer(buffer_local, [&](Buffer &buffer) { + _apply_vram(vram_local, [&](Vram &vram) { - if (buffer.owner(_session_cap) == false) return false; + if (vram.owner(_session_cap) == false) return false; - if (buffer.map.offset != Igd::Ggtt::Mapping::INVALID_OFFSET) { - Genode::error("cannot free mapped buffer"); + if (vram.map.offset != Igd::Ggtt::Mapping::INVALID_OFFSET) { + Genode::error("cannot free mapped vram"); /* XXX throw */ return false; } - _env.ep().dissolve(buffer); - _device.free_buffer(_heap, buffer.ds_cap); - _resource_guard.replenish(buffer.caps_used ? 1 : 0, - buffer.ram_used); + _env.ep().dissolve(vram); + _device.free_vram(_heap, vram.ds_cap); + _resource_guard.replenish(vram.caps_used ? 1 : 0, + vram.ram_used); return true; }); - _free_local_buffer(buffer_local); + _free_local_vram(vram_local); }; - _apply_buffer_local(id, lookup_and_free); + _apply_vram_local(id, lookup_and_free); } - Buffer_capability export_buffer(Buffer_id id) override + Vram_capability export_vram(Vram_id id) override { - Buffer_capability cap { }; - _apply_buffer_local(id, [&] (Buffer_local &buffer_local) { - if (_buffer_valid(buffer_local.buffer_cap)) - cap = buffer_local.buffer_cap; + Vram_capability cap { }; + _apply_vram_local(id, [&] (Vram_local &vram_local) { + if (_vram_valid(vram_local.vram_cap)) + cap = vram_local.vram_cap; }); return cap; } - void import_buffer(Buffer_capability cap, Buffer_id id) override + void import_vram(Vram_capability cap, Vram_id id) override { - if (_buffer_valid(cap) == false) + if (_vram_valid(cap) == false) throw Gpu::Session::Invalid_state(); try { - Buffer_local *buffer_local = new (_heap) Buffer_local(cap, 0, _buffer_space, id); + Vram_local *vram_local = new (_heap) Vram_local(cap, 0, _vram_space, id); - _apply_buffer(*buffer_local, [&](Buffer &buffer) { - buffer_local->size = buffer.size; return false; }); + _apply_vram(*vram_local, [&](Vram &vram) { + vram_local->size = vram.size; return false; }); - } catch (Id_space::Conflicting_id) { + } catch (Id_space::Conflicting_id) { throw Gpu::Session::Conflicting_id(); } catch (Cap_quota_guard::Limit_exceeded) { throw Gpu::Session::Out_of_caps(); @@ -1966,107 +1992,50 @@ class Gpu::Session_component : public Genode::Session_object } } - Genode::Dataspace_capability map_buffer(Gpu::Buffer_id id, - bool aperture, - Gpu::Mapping_attributes attrs) override + Genode::Dataspace_capability map_cpu(Gpu::Vram_id, + Gpu::Mapping_attributes) override { - /* treat GGTT mapped buffers as rw */ - if (!(attrs.readable && attrs.writeable)) - return Genode::Dataspace_capability(); - - Genode::Dataspace_capability map_cap; - - auto lookup_and_map = [&] (Buffer &buffer) { - if (buffer.owner(_session_cap) == false) { - Genode::error("GGTT mappings can only be done by buffer owner"); - return false; - } - - if (buffer.map.offset != Igd::Ggtt::Mapping::INVALID_OFFSET) { - Genode::error("buffer already mapped"); - return false; - } - /* GGTT mappings only require the heap */ - if (_resource_guard.avail_caps() == false) - throw Gpu::Session::Out_of_caps(); - - if (_resource_guard.avail_ram() == false) - throw Gpu::Session::Out_of_ram(); - - size_t caps_before = _env.pd().avail_caps().value; - size_t ram_before = _env.pd().avail_ram().value; - - Igd::Ggtt::Mapping const &map = - _device.map_buffer(_heap, buffer.ds_cap, aperture); - buffer.map.cap = map.cap; - buffer.map.offset = map.offset; - map_cap = buffer.map.cap; - - size_t caps_after = _env.pd().avail_caps().value; - size_t ram_after = _env.pd().avail_ram().value; - _resource_guard.withdraw(caps_before, caps_after, - ram_before , ram_after); - return true; - }; - - _apply_buffer_local(id, [&] (Buffer_local &buffer_local) { - _apply_buffer(buffer_local, lookup_and_map); }); - - return map_cap; + error("map_cpu: called not implemented"); + throw Mapping_vram_failed(); } - void unmap_buffer(Gpu::Buffer_id id) override + void unmap_cpu(Vram_id) override { - bool unmapped = false; - - auto lookup_and_unmap = [&] (Buffer &buffer) { - - if (buffer.owner(_session_cap) == false) { - Genode::error("GGTT unmappings can only be done by buffer owner"); - return false; - } - - if (!buffer.map.cap.valid()) { return false; } - - if (buffer.fenced != Buffer::INVALID_FENCE) { - _device.clear_tiling(buffer.fenced); - _vgpu.active_fences--; - } - - _device.unmap_buffer(_heap, buffer.map); - buffer.map.offset = Igd::Ggtt::Mapping::INVALID_OFFSET; - unmapped = true; - - return false; - }; - - _apply_buffer_local(id, [&](Buffer_local &buffer) { - _apply_buffer(buffer, lookup_and_unmap); }); - - if (!unmapped) { Genode::error("buffer not mapped"); } + error("unmap_cpu: called not implemented"); } - bool map_buffer_ppgtt(Gpu::Buffer_id id, Gpu::addr_t va) override + bool map_gpu(Vram_id id, size_t size, off_t offset, Gpu::Virtual_address va) override { - auto lookup_and_map = [&] (Buffer_local &buffer_local) { + auto lookup_and_map = [&] (Vram_local &vram_local) { - if (buffer_local.ppgtt_va_valid) { - Genode::error("buffer already mapped"); + if (vram_local.mappings.exists(offset)) { + Genode::error("vram already mapped at offset: ", Hex(offset)); return; } addr_t phys_addr = 0; - _apply_buffer(buffer_local, [&](Buffer &buffer) { - phys_addr = buffer.phys_addr; return false; }); + _apply_vram(vram_local, [&](Vram &vram) { + phys_addr = vram.phys_addr; return false; }); if (phys_addr == 0) { - _free_local_buffer(buffer_local); + _free_local_vram(vram_local); return; } - _vgpu.rcs_map_ppgtt(va, phys_addr, buffer_local.size); - buffer_local.ppgtt_va = va; - buffer_local.ppgtt_va_valid = true; + try { + _vgpu.rcs_map_ppgtt(va.va, phys_addr + offset, size); + } catch (Level_4_translation_table::Double_insertion) { + error("PPGTT: Double insertion: va: ", Hex(va.va), " offset: ", Hex(offset), + "size: ", Hex(size)); + throw Mapping_vram_failed(); + } catch(...) { + error("PPGTT: invalid address/range/alignment: va: ", Hex(va.va), + " offset: ", Hex(offset), + "size: ", Hex(size)); + throw Mapping_vram_failed(); + } + + new (_heap) Vram_local::Mapping(vram_local.mappings, offset, va.va, size); }; if (_resource_guard.avail_caps() == false) @@ -2078,7 +2047,7 @@ class Gpu::Session_component : public Genode::Session_object size_t caps_before = _env.pd().avail_caps().value; size_t ram_before = _env.pd().avail_ram().value; - _apply_buffer_local(id, lookup_and_map); + _apply_vram_local(id, lookup_and_map); size_t caps_after = _env.pd().avail_caps().value; size_t ram_after = _env.pd().avail_ram().value; @@ -2089,77 +2058,59 @@ class Gpu::Session_component : public Genode::Session_object return true; } - void unmap_buffer_ppgtt(Gpu::Buffer_id id, - Gpu::addr_t va) override + void unmap_gpu(Vram_id id, off_t offset, Gpu::Virtual_address va) override { - auto lookup_and_unmap = [&] (Buffer_local &buffer_local) { + auto lookup_and_unmap = [&] (Vram_local &vram_local) { - if (!buffer_local.ppgtt_va_valid) { - Genode::error("buffer not mapped"); - return; - } + vram_local.mappings.with_element(offset, + [&] (Vram_local::Mapping &mapping) { - if (buffer_local.ppgtt_va != va) { - Genode::error("buffer not mapped at ", Genode::Hex(va)); - return; - } - - _vgpu.rcs_unmap_ppgtt(va, buffer_local.size); - buffer_local.ppgtt_va_valid = false; + if (mapping.ppgtt_va != va.va) { + Genode::error("VRAM: not mapped at ", Hex(va.va), " offset: ", Hex(offset)); + return; + } + _vgpu.rcs_unmap_ppgtt(va.va, mapping.ppgtt_va_size); + destroy(_heap, &mapping); + }, + [&] () { error("VRAM: nothing mapped at offset ", Hex(offset)); } + ); }; - _apply_buffer_local(id, lookup_and_unmap); + _apply_vram_local(id, lookup_and_unmap); } - Gpu::addr_t query_buffer_ppgtt(Gpu::Buffer_id id) override - { - Gpu::addr_t result = (Gpu::addr_t)-1; - - auto lookup_va = [&] (Buffer_local &buffer_local) { - - if (!buffer_local.ppgtt_va_valid) { - Genode::error("buffer not mapped"); - return; - } - - result = buffer_local.ppgtt_va; - }; - _apply_buffer_local(id, lookup_va); - return result; - } - - bool set_tiling(Gpu::Buffer_id id, - Genode::uint32_t const mode) override + bool set_tiling_gpu(Vram_id id, off_t offset, + unsigned mode) override { if (_vgpu.active_fences > Igd::Device::Vgpu::MAX_FENCES) { Genode::error("no free fences left, already active: ", _vgpu.active_fences); return false; } - Buffer *b = nullptr; - auto lookup = [&] (Buffer &buffer) { - if (!buffer.map.cap.valid() || !buffer.owner(_session_cap)) { return false; } - b = &buffer; + Vram *v = nullptr; + auto lookup = [&] (Vram &vram) { + if (!vram.map.cap.valid() || !vram.owner(_session_cap)) { return false; } + v = &vram; return false; }; - _apply_buffer_local(id, [&](Buffer_local &buffer_local) { - _apply_buffer(buffer_local, lookup); + _apply_vram_local(id, [&](Vram_local &vram_local) { + _apply_vram(vram_local, lookup); }); - if (b == nullptr) { - Genode::error("attempt to set tiling for non-mapped or non-owned buffer"); + if (v == nullptr) { + Genode::error("attempt to set tiling for non-mapped or non-owned vram"); return false; } //XXX: support change of already fenced bo's fencing mode - if (b->fenced) return true; + if (v->fenced) return true; - Igd::size_t const size = b->size; - Genode::uint32_t const fenced = _device.set_tiling(b->map.offset, size, mode); + Igd::size_t const size = v->size; + Genode::uint32_t const fenced = _device.set_tiling(v->map.offset + offset, size, mode); - b->fenced = fenced; - if (fenced != Buffer::INVALID_FENCE) { _vgpu.active_fences++; } - return fenced != Buffer::INVALID_FENCE; + v->fenced = fenced; + if (fenced != Vram::INVALID_FENCE) { _vgpu.active_fences++; } + return fenced != Vram::INVALID_FENCE; } }; diff --git a/repos/os/src/drivers/gpu/intel/ppgtt.h b/repos/os/src/drivers/gpu/intel/ppgtt.h index 2012246fd7..09efb39379 100644 --- a/repos/os/src/drivers/gpu/intel/ppgtt.h +++ b/repos/os/src/drivers/gpu/intel/ppgtt.h @@ -215,6 +215,13 @@ namespace Genode class Genode::Level_4_translation_table { + public: + + class Misaligned {}; + class Invalid_address {}; + class Invalid_range {}; + class Double_insertion {}; + private: static constexpr size_t PAGE_SIZE_LOG2 = SIZE_LOG2_4KB; @@ -223,11 +230,6 @@ class Genode::Level_4_translation_table static constexpr size_t PAGE_SIZE = 1UL << PAGE_SIZE_LOG2; static constexpr size_t PAGE_MASK = ~((1UL << PAGE_SIZE_LOG2) - 1); - class Misaligned {}; - class Invalid_address {}; - class Invalid_range {}; - class Double_insertion {}; - struct Descriptor : Common_descriptor { using Common = Common_descriptor;