diff --git a/repos/dde_linux/lib/import/import-lx_emul_common.inc b/repos/dde_linux/lib/import/import-lx_emul_common.inc index e3c7689df2..b2fcc5a2d7 100644 --- a/repos/dde_linux/lib/import/import-lx_emul_common.inc +++ b/repos/dde_linux/lib/import/import-lx_emul_common.inc @@ -10,12 +10,8 @@ LD_OPT += --defsym=jiffies=jiffies_64 # SRC_CC += lx_emul/alloc.cc -SRC_CC += lx_emul/clock.cc SRC_CC += lx_emul/debug.cc SRC_CC += lx_emul/init.cc -SRC_CC += lx_emul/io_mem.cc -SRC_CC += lx_emul/io_port.cc -SRC_CC += lx_emul/irq.cc SRC_CC += lx_emul/log.cc SRC_CC += lx_emul/page_virt.cc SRC_CC += lx_emul/task.cc diff --git a/repos/dde_linux/src/include/lx_kit/dma_buffer.h b/repos/dde_linux/src/include/lx_kit/dma_buffer.h new file mode 100644 index 0000000000..47ae09ab02 --- /dev/null +++ b/repos/dde_linux/src/include/lx_kit/dma_buffer.h @@ -0,0 +1,42 @@ +/* + * \brief Lx_kit dma memory buffer + * \author Stefan Kalkowski + * \date 2021-03-25 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef _LX_KIT__DMA_BUFFER_H_ +#define _LX_KIT__DMA_BUFFER_H_ + +#include +#include + +namespace Lx_kit { class Dma_buffer; } + + +class Lx_kit::Dma_buffer : Platform::Dma_buffer, public Lx_kit::Mem_allocator::Buffer +{ + public: + + using Platform::Dma_buffer::Dma_buffer; + + size_t dma_addr() const override { + return Platform::Dma_buffer::dma_addr(); } + + size_t size() const override { + return Platform::Dma_buffer::size(); } + + size_t virt_addr() const override { + return (size_t) Platform::Dma_buffer::local_addr(); } + + Dataspace_capability cap() override { + return Platform::Dma_buffer::cap(); } +}; + +#endif /* _LX_KIT__DMA_BUFFER_H_ */ diff --git a/repos/dde_linux/src/include/lx_kit/memory.h b/repos/dde_linux/src/include/lx_kit/memory.h index 9a264b5ff2..8ce87d04d3 100644 --- a/repos/dde_linux/src/include/lx_kit/memory.h +++ b/repos/dde_linux/src/include/lx_kit/memory.h @@ -15,14 +15,14 @@ #define _LX_KIT__MEMORY_H_ #include -#include #include #include #include #include #include -namespace Platform { class Connection; }; +namespace Platform { class Connection; } + namespace Lx_kit { using namespace Genode; class Mem_allocator; @@ -31,33 +31,20 @@ namespace Lx_kit { class Lx_kit::Mem_allocator { - private: + public: - class Buffer + struct Buffer { - private: + virtual ~Buffer() {} - Ram_dataspace_capability _ram_ds_cap; - Attached_dataspace _ds; - addr_t const _dma_addr; - - public: - - Buffer(Region_map & rm, - Ram_dataspace_capability cap, - addr_t dma_addr) - : _ram_ds_cap(cap), _ds(rm, cap), _dma_addr(dma_addr) {} - - size_t dma_addr() const { return _dma_addr; } - size_t size() const { return _ds.size(); } - size_t virt_addr() const { - return (addr_t) _ds.local_addr(); } - - Attached_dataspace & ds() { return _ds; } - - Ram_dataspace_capability ram_ds_cap() { return _ram_ds_cap; } + virtual size_t dma_addr() const = 0; + virtual size_t size() const = 0; + virtual size_t virt_addr() const = 0; + virtual Dataspace_capability cap() = 0; }; + private: + struct Buffer_info { struct Key { addr_t addr; } key; @@ -97,9 +84,9 @@ class Lx_kit::Mem_allocator Heap & _heap; Platform::Connection & _platform; Cache _cache_attr; - Allocator_avl _mem; - Map _virt_to_dma { _heap }; - Map _dma_to_virt { _heap }; + Allocator_avl _mem { &_heap }; + Map _virt_to_dma { _heap }; + Map _dma_to_virt { _heap }; public: @@ -108,8 +95,8 @@ class Lx_kit::Mem_allocator Platform::Connection & platform, Cache cache_attr); - Attached_dataspace & alloc_dataspace(size_t size); - void free_dataspace(void *addr); + Buffer & alloc_buffer(size_t size); + void free_buffer(void *addr); Dataspace_capability attached_dataspace_cap(void *addr); void * alloc(size_t size, size_t align); diff --git a/repos/dde_linux/src/include/spec/x86/lx_kit/platform_session/connection.h b/repos/dde_linux/src/include/spec/x86/lx_kit/platform_session/connection.h index 2929a19fda..8ff8aba1a4 100644 --- a/repos/dde_linux/src/include/spec/x86/lx_kit/platform_session/connection.h +++ b/repos/dde_linux/src/include/spec/x86/lx_kit/platform_session/connection.h @@ -22,6 +22,7 @@ namespace Platform { struct Connection; + class Dma_buffer; using namespace Genode; } @@ -33,8 +34,8 @@ namespace Platform { struct Platform::Connection { - Env &_env; - + Env &_env; + Region_map &_rm { _env.rm() }; char _devices_node_buffer[4096u] { }; Constructible _devices_node { }; @@ -74,6 +75,12 @@ struct Platform::Connection void free_dma_buffer(Ram_dataspace_capability); addr_t dma_addr(Ram_dataspace_capability); + + template + auto retry_with_upgrade(Ram_quota ram, Cap_quota caps, FUNC func) -> decltype(func()) + { + return _legacy_platform->retry_with_upgrade(ram, caps, func); + } }; diff --git a/repos/dde_linux/src/lib/lx_emul/shared_dma_buffer.cc b/repos/dde_linux/src/lib/lx_emul/shared_dma_buffer.cc index a8b2217dae..d10d03cd19 100644 --- a/repos/dde_linux/src/lib/lx_emul/shared_dma_buffer.cc +++ b/repos/dde_linux/src/lib/lx_emul/shared_dma_buffer.cc @@ -11,43 +11,40 @@ * version 2. */ -#include - #include -#include +#include #include #include -struct genode_shared_dataspace : Genode::Attached_dataspace {}; +struct genode_shared_dataspace : Lx_kit::Dma_buffer {}; extern "C" struct genode_shared_dataspace * lx_emul_shared_dma_buffer_allocate(unsigned long size) { - Genode::Attached_dataspace & ds = - Lx_kit::env().memory.alloc_dataspace(size); + Lx_kit::Mem_allocator::Buffer & b = Lx_kit::env().memory.alloc_buffer(size); /* * We have to call virt_to_pages eagerly here, * to get contingous page objects registered */ - lx_emul_virt_to_pages(ds.local_addr(), size >> 12); - return static_cast(&ds); + lx_emul_virt_to_pages((void*)b.virt_addr(), size >> 12); + return static_cast(&b); } extern "C" void lx_emul_shared_dma_buffer_free(struct genode_shared_dataspace * ds) { - lx_emul_forget_pages(ds->local_addr(), ds->size()); - Lx_kit::env().memory.free_dataspace(ds->local_addr()); + lx_emul_forget_pages((void*)ds->virt_addr(), ds->size()); + Lx_kit::env().memory.free_buffer((void*)ds->virt_addr()); } Genode::addr_t genode_shared_dataspace_local_address(struct genode_shared_dataspace * ds) { - return (Genode::addr_t)ds->local_addr(); + return ds->virt_addr(); } diff --git a/repos/dde_linux/src/lib/lx_kit/memory.cc b/repos/dde_linux/src/lib/lx_kit/memory.cc index 0136f815c5..0d3c7e9c5c 100644 --- a/repos/dde_linux/src/lib/lx_kit/memory.cc +++ b/repos/dde_linux/src/lib/lx_kit/memory.cc @@ -13,9 +13,6 @@ /* Genode includes */ #include -#include -#include -#include /* local includes */ #include @@ -23,35 +20,9 @@ #include -Genode::Attached_dataspace & Lx_kit::Mem_allocator::alloc_dataspace(size_t size) +void Lx_kit::Mem_allocator::free_buffer(void * addr) { - Ram_dataspace_capability ds_cap; - - try { - Ram_dataspace_capability ds_cap = - _platform.alloc_dma_buffer(align_addr(size, 12), _cache_attr); - - Buffer & buffer = *new (_heap) - Buffer(_env.rm(), ds_cap, _platform.dma_addr(ds_cap)); - - /* map eager by touching all pages once */ - for (size_t sz = 0; sz < buffer.size(); sz += 4096) { - touch_read((unsigned char const volatile*)(buffer.virt_addr() + sz)); } - - _virt_to_dma.insert(buffer.virt_addr(), buffer); - _dma_to_virt.insert(buffer.dma_addr(), buffer); - - return buffer.ds(); - } catch (Out_of_caps) { - _platform.free_dma_buffer(ds_cap); - throw; - } -} - - -void Lx_kit::Mem_allocator::free_dataspace(void * addr) -{ - Buffer *buffer = nullptr; + Buffer * buffer = nullptr; _virt_to_dma.apply(Buffer_info::Query_addr(addr), [&] (Buffer_info const & info) { @@ -59,7 +30,7 @@ void Lx_kit::Mem_allocator::free_dataspace(void * addr) }); if (!buffer) { - warning(__func__, ": no buffer for addr: ", addr, " found"); + warning(__func__, ": no memory buffer for addr: ", addr, " found"); return; } @@ -69,11 +40,7 @@ void Lx_kit::Mem_allocator::free_dataspace(void * addr) _virt_to_dma.remove(Buffer_info::Query_addr(virt_addr)); _dma_to_virt.remove(Buffer_info::Query_addr(dma_addr)); - Ram_dataspace_capability ds_cap = buffer->ram_ds_cap(); - destroy(_heap, buffer); - - _platform.free_dma_buffer(ds_cap); } @@ -83,7 +50,7 @@ Genode::Dataspace_capability Lx_kit::Mem_allocator::attached_dataspace_cap(void _virt_to_dma.apply(Buffer_info::Query_addr(addr), [&] (Buffer_info const & info) { - ret = info.buffer.ds().cap(); + ret = info.buffer.cap(); }); return ret; @@ -118,10 +85,9 @@ void * Lx_kit::Mem_allocator::alloc(size_t size, size_t align) * and physical addresses of a multi-page allocation are always * contiguous. */ - Attached_dataspace & ds = alloc_dataspace(max(size + 1, - min_buffer_size)); + Buffer & buffer = alloc_buffer(max(size + 1, min_buffer_size)); - _mem.add_range((addr_t)ds.local_addr(), ds.size() - 1); + _mem.add_range(buffer.virt_addr(), buffer.size() - 1); /* re-try allocation */ return _mem.alloc_aligned(size, (unsigned)log2(align)).convert( @@ -132,7 +98,6 @@ void * Lx_kit::Mem_allocator::alloc(size_t size, size_t align) [&] (Range_allocator::Alloc_error) -> void * { error("memory allocation failed for ", size, " align ", align); - backtrace(); return nullptr; } ); } @@ -198,6 +163,4 @@ Lx_kit::Mem_allocator::Mem_allocator(Genode::Env & env, Heap & heap, Platform::Connection & platform, Cache cache_attr) -: - _env(env), _heap(heap), _platform(platform), - _cache_attr(cache_attr), _mem(&heap) {} +: _env(env), _heap(heap), _platform(platform), _cache_attr(cache_attr) {} diff --git a/repos/dde_linux/src/lib/lx_kit/memory_dma.cc b/repos/dde_linux/src/lib/lx_kit/memory_dma.cc new file mode 100644 index 0000000000..8e38a32f01 --- /dev/null +++ b/repos/dde_linux/src/lib/lx_kit/memory_dma.cc @@ -0,0 +1,37 @@ +/* + * \brief Lx_kit DMA-capable memory allocation backend + * \author Stefan Kalkowski + * \date 2021-03-25 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +/* Genode includes */ +#include + +/* local includes */ +#include +#include + + +Lx_kit::Mem_allocator::Buffer & +Lx_kit::Mem_allocator::alloc_buffer(size_t size) +{ + size = align_addr(size, 12); + + Buffer & buffer = *static_cast(new (_heap) + Lx_kit::Dma_buffer(_platform, size, _cache_attr)); + + /* map eager by touching all pages once */ + for (size_t sz = 0; sz < buffer.size(); sz += 4096) { + touch_read((unsigned char const volatile*)(buffer.virt_addr() + sz)); } + + _virt_to_dma.insert(buffer.virt_addr(), buffer); + _dma_to_virt.insert(buffer.dma_addr(), buffer); + return buffer; +} diff --git a/repos/dde_linux/src/lib/lx_kit/memory_non_dma.cc b/repos/dde_linux/src/lib/lx_kit/memory_non_dma.cc new file mode 100644 index 0000000000..7ab2e68183 --- /dev/null +++ b/repos/dde_linux/src/lib/lx_kit/memory_non_dma.cc @@ -0,0 +1,58 @@ +/* + * \brief Lx_kit without DMA-capable memory allocation backend + * \author Stefan Kalkowski + * \date 2021-03-25 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +/* Genode includes */ +#include +#include + +/* local includes */ +#include + +using namespace Genode; + +class Non_dma_buffer : Attached_ram_dataspace, + public Lx_kit::Mem_allocator::Buffer +{ + public: + + using Attached_ram_dataspace::Attached_ram_dataspace; + + size_t dma_addr() const override { return 0UL; } + + size_t size() const override { + return Attached_ram_dataspace::size(); } + + size_t virt_addr() const override { + return (size_t) Attached_ram_dataspace::local_addr(); } + + Dataspace_capability cap() override { + return Attached_ram_dataspace::cap(); } +}; + + +Lx_kit::Mem_allocator::Buffer & +Lx_kit::Mem_allocator::alloc_buffer(size_t size) +{ + size = align_addr(size, 12); + + Buffer & buffer = *static_cast(new (_heap) + Non_dma_buffer(_env.ram(), _env.rm(), size, _cache_attr)); + + /* map eager by touching all pages once */ + for (size_t sz = 0; sz < buffer.size(); sz += 4096) { + touch_read((unsigned char const volatile*)(buffer.virt_addr() + sz)); } + + _virt_to_dma.insert(buffer.virt_addr(), buffer); + _dma_to_virt.insert(buffer.dma_addr(), buffer); + return buffer; +} diff --git a/repos/pc/lib/import/import-pc_lx_emul.mk b/repos/pc/lib/import/import-pc_lx_emul.mk index 39bbb170a0..d9de8e04bf 100644 --- a/repos/pc/lib/import/import-pc_lx_emul.mk +++ b/repos/pc/lib/import/import-pc_lx_emul.mk @@ -12,6 +12,10 @@ include $(call select_from_repositories,lib/import/import-lx_emul_common.inc) # Handle specific source requirements CC_OPT_drivers/usb/host/xhci-trace += -I$(LX_SRC_DIR)/drivers/usb/host +SRC_CC += lx_emul/clock.cc +SRC_CC += lx_emul/io_mem.cc +SRC_CC += lx_emul/io_port.cc +SRC_CC += lx_emul/irq.cc SRC_C += lx_emul/shadow/kernel/dma/mapping.c SRC_C += lx_emul/shadow/kernel/irq/spurious.c SRC_C += lx_emul/shadow/kernel/rcu/tree.c @@ -22,4 +26,5 @@ SRC_C += lx_emul/shadow/mm/memblock.c SRC_CC += lx_emul/pci_config_space.cc SRC_CC += lx_emul/pci_init.cc SRC_CC += lx_kit/device.cc +SRC_CC += lx_kit/memory_dma.cc SRC_CC += lx_kit/spec/x86/platform.cc