/* * \brief PPGTT translation table allocator * \author Josef Soentgen * \data 2017-03-15 */ /* * Copyright (C) 2017 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. */ #ifndef _PPGTT_ALLOCATOR_H_ #define _PPGTT_ALLOCATOR_H_ /* local includes */ #include #include #include namespace Igd { class Ppgtt_allocator; } class Igd::Ppgtt_allocator : public Genode::Translation_table_allocator { private: Genode::Region_map &_rm; Genode::Allocator_guard &_guard; Utils::Backend_alloc &_backend; enum { ELEMENTS = 256, }; Utils::Address_map _map { }; public: Ppgtt_allocator(Genode::Region_map &rm, Genode::Allocator_guard &guard, Utils::Backend_alloc &backend) : _rm(rm), _guard(guard), _backend(backend) { } /************************* ** Allocator interface ** *************************/ bool alloc(size_t size, void **out_addr) override { Genode::Ram_dataspace_capability ds = _backend.alloc(_guard, size); if (!ds.valid()) { return false; } *out_addr = _rm.attach(ds); return _map.add(ds, *out_addr); } void free(void *addr, size_t) override { if (addr == nullptr) { return; } Genode::Ram_dataspace_capability cap = _map.remove(addr); if (!cap.valid()) { Genode::error("could not lookup capability for addr: ", addr); return; } _rm.detach(addr); _backend.free(_guard, cap); } bool need_size_for_free() const override { return false; } size_t overhead(size_t) const override { return 0; } /******************************************* ** Translation_table_allocator interface ** *******************************************/ void *phys_addr(void *va) override { if (va == nullptr) { return nullptr; } typename Utils::Address_map::Element *e = _map.phys_addr(va); return e ? (void*)e->pa : nullptr; } void *virt_addr(void *pa) override { if (pa == nullptr) { return nullptr; } typename Utils::Address_map::Element *e = _map.virt_addr(pa); return e ? (void*)e->va : nullptr; } }; #endif /* _PPGTT_ALLOCATOR_H_ */