mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 17:52:52 +00:00
lx_kit/lx_emul: make memory backend configureable
* Drivers have to use lx_kit/memory_dma.cc * Protocol-stacks use lx_kit/memory_non_dma.cc * Moreover the device-dependent lx_emul parts get removed from the common lx_emul import rules Fix #4443
This commit is contained in:
parent
d473bed4b7
commit
0fa695dbd7
@ -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
|
||||
|
42
repos/dde_linux/src/include/lx_kit/dma_buffer.h
Normal file
42
repos/dde_linux/src/include/lx_kit/dma_buffer.h
Normal file
@ -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 <lx_kit/memory.h>
|
||||
#include <platform_session/dma_buffer.h>
|
||||
|
||||
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<void>(); }
|
||||
|
||||
Dataspace_capability cap() override {
|
||||
return Platform::Dma_buffer::cap(); }
|
||||
};
|
||||
|
||||
#endif /* _LX_KIT__DMA_BUFFER_H_ */
|
@ -15,14 +15,14 @@
|
||||
#define _LX_KIT__MEMORY_H_
|
||||
|
||||
#include <base/allocator_avl.h>
|
||||
#include <base/attached_dataspace.h>
|
||||
#include <base/cache.h>
|
||||
#include <base/env.h>
|
||||
#include <base/heap.h>
|
||||
#include <lx_kit/byte_range.h>
|
||||
#include <lx_kit/map.h>
|
||||
|
||||
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<void*>(); }
|
||||
|
||||
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<Buffer_info> _virt_to_dma { _heap };
|
||||
Map<Buffer_info> _dma_to_virt { _heap };
|
||||
Allocator_avl _mem { &_heap };
|
||||
Map<Buffer_info> _virt_to_dma { _heap };
|
||||
Map<Buffer_info> _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);
|
||||
|
@ -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<Xml_node> _devices_node { };
|
||||
|
||||
@ -74,6 +75,12 @@ struct Platform::Connection
|
||||
void free_dma_buffer(Ram_dataspace_capability);
|
||||
|
||||
addr_t dma_addr(Ram_dataspace_capability);
|
||||
|
||||
template <typename FUNC>
|
||||
auto retry_with_upgrade(Ram_quota ram, Cap_quota caps, FUNC func) -> decltype(func())
|
||||
{
|
||||
return _legacy_platform->retry_with_upgrade<FUNC>(ram, caps, func);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -11,43 +11,40 @@
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <base/attached_dataspace.h>
|
||||
|
||||
#include <lx_kit/env.h>
|
||||
#include <lx_kit/memory.h>
|
||||
#include <lx_kit/dma_buffer.h>
|
||||
#include <lx_emul/page_virt.h>
|
||||
#include <lx_emul/shared_dma_buffer.h>
|
||||
|
||||
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<void>(), size >> 12);
|
||||
return static_cast<genode_shared_dataspace*>(&ds);
|
||||
lx_emul_virt_to_pages((void*)b.virt_addr(), size >> 12);
|
||||
return static_cast<genode_shared_dataspace*>(&b);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void
|
||||
lx_emul_shared_dma_buffer_free(struct genode_shared_dataspace * ds)
|
||||
{
|
||||
lx_emul_forget_pages(ds->local_addr<void>(), ds->size());
|
||||
Lx_kit::env().memory.free_dataspace(ds->local_addr<void>());
|
||||
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<void>();
|
||||
return ds->virt_addr();
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,9 +13,6 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <os/backtrace.h>
|
||||
#include <platform_session/connection.h>
|
||||
#include <util/touch.h>
|
||||
|
||||
/* local includes */
|
||||
#include <lx_kit/memory.h>
|
||||
@ -23,35 +20,9 @@
|
||||
#include <lx_kit/byte_range.h>
|
||||
|
||||
|
||||
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<void>(), ds.size() - 1);
|
||||
_mem.add_range(buffer.virt_addr(), buffer.size() - 1);
|
||||
|
||||
/* re-try allocation */
|
||||
return _mem.alloc_aligned(size, (unsigned)log2(align)).convert<void *>(
|
||||
@ -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) {}
|
||||
|
37
repos/dde_linux/src/lib/lx_kit/memory_dma.cc
Normal file
37
repos/dde_linux/src/lib/lx_kit/memory_dma.cc
Normal file
@ -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 <util/touch.h>
|
||||
|
||||
/* local includes */
|
||||
#include <lx_kit/dma_buffer.h>
|
||||
#include <lx_kit/memory.h>
|
||||
|
||||
|
||||
Lx_kit::Mem_allocator::Buffer &
|
||||
Lx_kit::Mem_allocator::alloc_buffer(size_t size)
|
||||
{
|
||||
size = align_addr(size, 12);
|
||||
|
||||
Buffer & buffer = *static_cast<Buffer*>(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;
|
||||
}
|
58
repos/dde_linux/src/lib/lx_kit/memory_non_dma.cc
Normal file
58
repos/dde_linux/src/lib/lx_kit/memory_non_dma.cc
Normal file
@ -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 <base/attached_ram_dataspace.h>
|
||||
#include <util/touch.h>
|
||||
|
||||
/* local includes */
|
||||
#include <lx_kit/memory.h>
|
||||
|
||||
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<void>(); }
|
||||
|
||||
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<Buffer*>(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;
|
||||
}
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user