From 78c752b1c7053ee1732d2eb09f23edab3ad7f6b6 Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Mon, 4 Mar 2013 11:20:42 +0100 Subject: [PATCH] usb: Rewrote back-end allocators Allocate back-end memory dynamically. --- dde_linux/lib/mk/arm/usb.inc | 2 - dde_linux/run/usb_net.run | 31 +- dde_linux/src/lib/usb/arm/mem.cc | 18 - .../src/lib/usb/include/arm/platform/lx_mem.h | 26 ++ dde_linux/src/lib/usb/include/mem.h | 251 ------------ .../src/lib/usb/include/x86/platform/lx_mem.h | 25 ++ dde_linux/src/lib/usb/lx_emul.cc | 387 +++++++++++------- dde_linux/src/lib/usb/nic/nic.cc | 3 +- dde_linux/src/lib/usb/pci_driver.cc | 15 +- 9 files changed, 332 insertions(+), 426 deletions(-) delete mode 100644 dde_linux/src/lib/usb/arm/mem.cc create mode 100644 dde_linux/src/lib/usb/include/arm/platform/lx_mem.h delete mode 100644 dde_linux/src/lib/usb/include/mem.h create mode 100644 dde_linux/src/lib/usb/include/x86/platform/lx_mem.h diff --git a/dde_linux/lib/mk/arm/usb.inc b/dde_linux/lib/mk/arm/usb.inc index 462de9e430..ae88dd2195 100644 --- a/dde_linux/lib/mk/arm/usb.inc +++ b/dde_linux/lib/mk/arm/usb.inc @@ -1,6 +1,4 @@ SRC_C += platform_device.c -SRC_CC += mem.cc INC_DIR += $(LIB_INC_DIR)/arm vpath platform_device.c $(LIB_DIR)/arm -vpath mem.cc $(LIB_DIR)/arm diff --git a/dde_linux/run/usb_net.run b/dde_linux/run/usb_net.run index 399db51b28..fd1202b00c 100644 --- a/dde_linux/run/usb_net.run +++ b/dde_linux/run/usb_net.run @@ -17,6 +17,9 @@ build { test/lwip/http_srv } +lappend_if [have_spec acpi] build_components drivers/acpi +lappend_if [have_spec pci] build_components drivers/pci/device_pd + create_boot_directory # @@ -58,7 +61,29 @@ set config { - + } + +append_if [have_spec acpi] config { + + + + + + + + + + + + } + +append_if [expr ![have_spec acpi] && [have_spec pci]] config { + + + + } + +append config { } @@ -75,6 +100,10 @@ set boot_modules { ld.lib.so libc.lib.so libc_log.lib.so lwip.lib.so test-lwip_httpsrv } +lappend_if [have_spec acpi] boot_modules acpi_drv +lappend_if [have_spec pci] boot_modules pci_drv +lappend_if [have_spec nova] boot_modules pci_device_pd + build_boot_image $boot_modules # vi: set ft=tcl : diff --git a/dde_linux/src/lib/usb/arm/mem.cc b/dde_linux/src/lib/usb/arm/mem.cc deleted file mode 100644 index 9327d6d37f..0000000000 --- a/dde_linux/src/lib/usb/arm/mem.cc +++ /dev/null @@ -1,18 +0,0 @@ -/* - * \brief Backend for allocating DMA memory on ARM - * \author Alexander Boettcher - * \date 2013-02-19 - */ - -/* - * Copyright (C) 2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#include -#include "mem.h" - -Genode::Ram_dataspace_capability Genode::Mem::alloc_dma_buffer(size_t size) { - return Genode::env()->ram_session()->alloc(size, false); } diff --git a/dde_linux/src/lib/usb/include/arm/platform/lx_mem.h b/dde_linux/src/lib/usb/include/arm/platform/lx_mem.h new file mode 100644 index 0000000000..30fcfda91b --- /dev/null +++ b/dde_linux/src/lib/usb/include/arm/platform/lx_mem.h @@ -0,0 +1,26 @@ +/* + * \brief Platform specific part of memory allocation + * \author Alexander Boettcher + * \date 2013-03-18 + */ + +/* + * Copyright (C) 2013-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _ARM__PLATFORM__LX_MEM_ +#define _ARM__PLATFORM__LX_MEM_ + +class Backend_memory { + + public: + + static Genode::Ram_dataspace_capability alloc(Genode::addr_t size, + bool cached) { + return Genode::env()->ram_session()->alloc(size, cached); } +}; + +#endif /* _ARM__PLATFORM__LX_MEM_ */ diff --git a/dde_linux/src/lib/usb/include/mem.h b/dde_linux/src/lib/usb/include/mem.h deleted file mode 100644 index 750b806873..0000000000 --- a/dde_linux/src/lib/usb/include/mem.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * \brief Memory pool - * \author Sebastian Sumpf - * \date 2012-06-18 - */ - -/* - * Copyright (C) 2012-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _MEM_H_ -#define _MEM_H_ - -#include -#include -#include - -/********************* - ** linux/dmapool.h ** - *********************/ - -namespace Genode { - - /** - * Memory back-end - */ - class Mem - { - /* configurable sizes of memory pools */ - enum - { - MEM_POOL_SHARE = 3 - }; - - private: - - addr_t _base; /* virt base of pool */ - addr_t _base_phys; /* phys base of pool */ - size_t _size; /* size of backng store */ - Allocator_avl _range; /* range allocator for pool */ - addr_t *_zones; /* bases of zones */ - int _zone_count; /* number of zones */ - int _zone_alloc; /* currently allocated zones */ - - Ram_dataspace_capability _ds_cap; /* backing store */ - - /** - * Allocates memory which can be used for DMA. - */ - Genode::Ram_dataspace_capability alloc_dma_buffer(size_t size); - - /** - * Private constructor - */ - Mem(size_t size, bool cached = true) - : _size(size), _range(env()->heap()),_zone_count(0), _zone_alloc(0) - { - if (cached) - _ds_cap = env()->ram_session()->alloc(_size, cached); - else - _ds_cap = alloc_dma_buffer(_size); - - _base_phys = Dataspace_client(_ds_cap).phys_addr(); - _base = (addr_t)env()->rm_session()->attach(_ds_cap); - - dde_kit_log(DEBUG_DMA, "New DMA range [%lx-%lx)", _base, _base + _size); - _range.add_range(_base, _size); - } - - /** - * Convert 'Mem' addres to zone address - */ - void *_to_zone(void const *addr, int i) - { - if (i < 0) - return (void *)addr; - - addr_t zone_base = _zones[i]; - addr_t offset = (addr_t)addr - _base; - return (void *)(zone_base + offset); - } - - /** - * Convert zone addres to 'Mem' address - */ - void *_from_zone(void const *addr, int i) - { - if (i < 0) - return (void *)addr; - - addr_t zone_base = _zones[i]; - addr_t offset = (addr_t)addr - zone_base; - return (void *)(_base + offset); - } - - /** - * Memory usable by back-end allocators - */ - static size_t _mem_avail() { - return env()->ram_session()->avail() - (1024 * 1024); } - - public: - - /** - * Memory zone within Mem allocator - */ - class Zone_alloc : public Allocator - { - private: - - Mem *_pool; /* pool of zone */ - int _zone; /* zone number */ - addr_t _base; /* base address of zone */ - size_t _size; /* size of zone */ - - public: - - Zone_alloc(Mem *pool, int zone, addr_t base, size_t size) - : _pool(pool), _zone(zone), _base(base), _size(size) { } - - - /************************* - ** Alocator interface ** - *************************/ - - bool alloc(size_t size, void **out_addr) - { - *out_addr = _pool->alloc(size, _zone); - if (!*out_addr) { - PERR("Zone of %zu bytes allocation failed", size); - return false; - } - return true; - } - - void free(void *addr, size_t /* size */) { _pool->free(addr, _zone); } - size_t overhead(size_t size) { return 0; } - - /** - * Check if address matches zone - */ - bool match(void const *addr) - { - addr_t a = (addr_t)addr; - bool ret = ((a >= _base) && (a < (_base + _size))); - return ret; - } - - /** - * Retrieve virt to phys mapping - */ - addr_t phys_addr(void const *addr) { return _pool->phys_addr(addr, _zone); } - }; - - /** - * Gernal purpose memory pool - */ - static Mem* pool() - { - static Mem _p(_mem_avail() / MEM_POOL_SHARE); - return &_p; - } - - - /** - * DMA memory pool - */ - static Mem* dma() - { - static Mem _p(_mem_avail() - (_mem_avail() / MEM_POOL_SHARE), false); - return &_p; - } - - - /** - * Allocator interface - */ - void *alloc(size_t size, int zone = -1, int align = 2) - { - void *addr; - if (_range.alloc_aligned(size, &addr, align).is_error()) { - PERR("Memory allocation of %zu bytes failed", size); - return 0; - } - - return _to_zone(addr, zone); - } - - /** - * Free addr in zone - */ - void free(void *addr, int zone = -1) { _range.free(_from_zone(addr, zone)); } - - /** - * Get phys for virt address - */ - addr_t phys_addr(void const *addr, int zone = - 1) - { - addr_t a = (addr_t)_from_zone(addr, zone); - if (a < _base || a >= _base + _size) { - PERR("No DMA phys addr for %lx zone: %d", a, zone); - return 0; - } - return (a - _base) + _base_phys; - } - - /** - * Iinit allocator with count zones - */ - void init_zones(int count) - { - if (_zone_count) - return; - - _zones = (addr_t *)env()->heap()->alloc(count * sizeof(addr_t)); - _zone_count = count; - - for (int i = 0; i < _zone_count; i++) { - _zones[i] = (addr_t)env()->rm_session()->attach(_ds_cap); - dde_kit_log(DEBUG_DMA, "Zone %d: base: %lx end %lx", i, _zones[i], _zones[i] + _size); - } - - PINF("Registered %d zone allocators", count); - } - - /** - * Create new zone allocator - * - * 'init_zones' must have been called beforehand - */ - Zone_alloc *new_zone_allocator() - { - if(_zone_alloc >= _zone_count) { - PERR("Zone allocators exhausted"); - return 0; - } - - Zone_alloc *zone = new(env()->heap()) Zone_alloc(this, - _zone_alloc, - _zones[_zone_alloc], - _size); - _zone_alloc++; - return zone; - } - }; -} - -#endif /* _MEM_H_ */ diff --git a/dde_linux/src/lib/usb/include/x86/platform/lx_mem.h b/dde_linux/src/lib/usb/include/x86/platform/lx_mem.h new file mode 100644 index 0000000000..45530b1003 --- /dev/null +++ b/dde_linux/src/lib/usb/include/x86/platform/lx_mem.h @@ -0,0 +1,25 @@ +/* + * \brief Platform specific part of memory allocation + * \author Alexander Boettcher + * \date 2013-03-18 + */ + +/* + * Copyright (C) 2013-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _X86__PLATFORM__LX_MEM_ +#define _X86__PLATFORM__LX_MEM_ + +class Backend_memory { + + public: + + static Genode::Ram_dataspace_capability alloc(Genode::addr_t size, + bool cached); +}; + +#endif /* _X86__PLATFORM__LX_MEM_ */ diff --git a/dde_linux/src/lib/usb/lx_emul.cc b/dde_linux/src/lib/usb/lx_emul.cc index 4a64107cbb..b7a5c61d92 100644 --- a/dde_linux/src/lib/usb/lx_emul.cc +++ b/dde_linux/src/lib/usb/lx_emul.cc @@ -20,10 +20,10 @@ #include /* Local includes */ -#include "mem.h" #include "routine.h" #include "signal.h" #include "lx_emul.h" +#include "platform/lx_mem.h" /* DDE kit includes */ extern "C" { @@ -38,121 +38,217 @@ extern "C" { #if VERBOSE_LX_EMUL #define TRACE dde_kit_printf("\033[35m%s\033[0m called\n", __PRETTY_FUNCTION__) -#define UNSUPPORTED dde_kit_printf("\033[31m%s\033[0m unsupported arguments\n", __PRETTY_FUNCTION__) #else #define TRACE -#define UNSUPPORTED #endif namespace Genode { - - class Slab_alloc : public Slab - { - private: - - Mem::Zone_alloc *_allocator; - - size_t _calculate_block_size(size_t object_size) - { - size_t block_size = 8 * (object_size + sizeof(Slab_entry)) + sizeof(Slab_block); - return align_addr(block_size, 12); - } - - public: - - Slab_alloc(size_t object_size, Mem::Zone_alloc *allocator) - : Slab(object_size, _calculate_block_size(object_size), 0, allocator), - _allocator(allocator) { } - - inline void *alloc() - { - void *result; - return (Slab::alloc(slab_size(), &result) ? result : 0); - } - - bool match(void const *addr) { return _allocator->match(addr); } - addr_t phys_addr(void const *addr) { return _allocator->phys_addr(addr); } - }; + class Slab_backend_alloc; + class Slab_alloc; } - -class Malloc +/** + * Back-end allocator for Genode's slab allocator + */ +class Genode::Slab_backend_alloc : public Genode::Allocator, + public Genode::Rm_connection { private: - Genode::Mem *_pool; - - enum { - SLAB_START_LOG2 = 3, /* 8 B */ - SLAB_STOP_LOG2 = 16, /* 64 KB */ - NUM_SLABS = (SLAB_STOP_LOG2 - SLAB_START_LOG2) + 1 + enum { + VM_SIZE = 10 * 1024 * 1024, /* size of VM region to reserve */ + BLOCK_SIZE = 768 * 1024, /* 1 MB */ + ELEMENTS = VM_SIZE / BLOCK_SIZE, /* MAX number of dataspaces in VM */ }; - /* slab allocator using Mem as back-end */ - Genode::Slab_alloc *_allocator[NUM_SLABS]; + addr_t _base; /* virt. base address */ + bool _cached; /* non-/cached RAM */ + Ram_dataspace_capability _ds_cap[ELEMENTS]; /* dataspaces to put in VM */ + addr_t _ds_phys[ELEMENTS]; /* physical bases of dataspaces */ + int _index; /* current index in ds_cap */ + Allocator_avl _range; /* manage allocations */ - void _init_slabs() + bool _alloc_block() { - using namespace Genode; - _pool->init_zones(NUM_SLABS); - for (unsigned i = SLAB_START_LOG2; i <= SLAB_STOP_LOG2; i++) { - Mem::Zone_alloc *allocator = _pool->new_zone_allocator(); - _allocator[i - SLAB_START_LOG2] = new (env()->heap()) Slab_alloc(1U << i, allocator); + if (_index == ELEMENTS) { + PERR("Slab-backend exhausted!"); + return false; } - } - /** - * Return slab for 'struct dma_pool' of size - */ - int _dma_pool_slab(Genode::size_t size) - { - int msb = Genode::log2(size); - if (size > (1U << msb)) - msb++; + try { + _ds_cap[_index] = Backend_memory::alloc(BLOCK_SIZE, _cached); + /* attach at index * BLOCK_SIZE */ + Rm_connection::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); - /* take next chunk */ - return msb++; + /* lookup phys. address */ + _ds_phys[_index] = Dataspace_client(_ds_cap[_index]).phys_addr(); + } catch (...) { return false; } + + /* return base + offset in VM area */ + addr_t block_base = _base + (_index * BLOCK_SIZE); + ++_index; + + _range.add_range(block_base, BLOCK_SIZE); + return true; } public: - Malloc(Genode::Mem *pool) : _pool(pool) { _init_slabs(); } - - /** - * General purpose allcator - */ - static Malloc *mem() + Slab_backend_alloc(bool cached) + : Rm_connection(0, VM_SIZE), _cached(cached), _index(0), + _range(env()->heap()) { - static Malloc _m(Genode::Mem::pool()); - return &_m; + /* reserver attach us, anywere */ + _base = env()->rm_session()->attach(dataspace()); } /** - * DMA allocator + * Allocate */ - static Malloc *dma() + bool alloc(size_t size, void **out_addr) { - static Malloc _m(Genode::Mem::dma()); - return &_m; + bool done = _range.alloc(size, out_addr); + + if (done) + return done; + + done = _alloc_block(); + if (!done) { + PERR("Backend allocator exhausted\n"); + return false; + } + + return _range.alloc(size, out_addr); } + void free(void *addr, size_t /* size */) { } + size_t overhead(size_t size) { return 0; } + /** - * Alloc with alignment (uses back-end when alingment is > 2) + * Return phys address for given virtual addr. */ - void *alloc(Genode::size_t size, int align) + addr_t phys_addr(addr_t addr) { - if (align <= 2) - return alloc(size); + if (addr < _base || addr >= (_base + VM_SIZE)) + return ~0UL; - return _pool->alloc(size, -1, align); + int index = (addr - _base) / BLOCK_SIZE; + + /* physical base of dataspace */ + addr_t phys = _ds_phys[index]; + + if (!phys) + return ~0UL; + + /* add offset */ + phys += (addr - _base - (index * BLOCK_SIZE)); + return phys; } + addr_t start() const { return _base; } + addr_t end() const { return _base + VM_SIZE - 1; } +}; + + +/** + * Slab allocator using our back-end allocator + */ +class Genode::Slab_alloc : public Genode::Slab +{ + private: + + Slab_backend_alloc *_allocator; + + size_t _calculate_block_size(size_t object_size) + { + size_t block_size = 8 * (object_size + sizeof(Slab_entry)) + sizeof(Slab_block); + return align_addr(block_size, 12); + } + + public: + + Slab_alloc(size_t object_size, Slab_backend_alloc *allocator) + : Slab(object_size, _calculate_block_size(object_size), 0, allocator), + _allocator(allocator) { } + + inline addr_t alloc() + { + addr_t result; + return (Slab::alloc(slab_size(), (void **)&result) ? result : 0); + } + + addr_t phys_addr(addr_t addr) { return _allocator->phys_addr(addr); } +}; + + +/** + * Memory interface used used for Linux emulation + */ +class Malloc +{ + private: + + enum { + SLAB_START_LOG2 = 3, /* 8 B */ + SLAB_STOP_LOG2 = 16, /* 64 KB */ + NUM_SLABS = (SLAB_STOP_LOG2 - SLAB_START_LOG2) + 1, + }; + + typedef Genode::addr_t addr_t; + typedef Genode::Slab_alloc Slab_alloc; + typedef Genode::Slab_backend_alloc Slab_backend_alloc; + + Slab_alloc *_allocator[NUM_SLABS]; + bool _cached; /* cached or un-cached memory */ + addr_t _start; /* VM region of this allocator */ + addr_t _end; + + /** + * Set 'value' at 'addr' + */ + void _set_at(addr_t addr, addr_t value) { *((addr_t *)addr) = value; } + + /** + * Retrieve slab index belonging to given address + */ + unsigned _slab_index(Genode::addr_t **addr) + { + using namespace Genode; + /* get index */ + addr_t index = *(*addr - 1); + + /* + * If index large, we use aligned memory, retrieve beginning of slab entry + * and read index from there + */ + if (index > 32) { + *addr = (addr_t *)*(*addr - 1); + index = *(*addr - 1); + } + + return index; + } + + public: + + Malloc(Slab_backend_alloc *alloc, bool cached) + : _cached(cached), _start(alloc->start()), _end(alloc->end()) + { + /* init slab allocators */ + for (unsigned i = SLAB_START_LOG2; i <= SLAB_STOP_LOG2; i++) + _allocator[i - SLAB_START_LOG2] = new (Genode::env()->heap()) + Slab_alloc(1U << i, alloc); + } /** * Alloc in slabs */ - void *alloc(Genode::size_t size) + void *alloc(Genode::size_t size, int align = 0, Genode::addr_t *phys = 0) { + using namespace Genode; + /* += slab index + aligment size */ + size += sizeof(addr_t) + (align > 2 ? (1 << align) : 0); + int msb = Genode::log2(size); if (size > (1U << msb)) @@ -162,86 +258,74 @@ class Malloc msb = SLAB_STOP_LOG2; if (msb > SLAB_STOP_LOG2) { - PINF("Slab too large %u", 1U << msb); - return _pool->alloc(size); + PERR("Slab too large %u reqested %zu cached %d", 1U << msb, size, _cached); + return 0; } - return _allocator[msb - SLAB_START_LOG2]->alloc(); - } - - - /** - * Free from slabs - */ - void free(void const *addr) - { - - for (register unsigned i = SLAB_START_LOG2; i <= SLAB_STOP_LOG2; i++) { - Genode::Slab_alloc *slab = _allocator[i - SLAB_START_LOG2]; - - if (!slab->match(addr)) - continue; - - slab->free((void *)addr); - return; + addr_t addr = _allocator[msb - SLAB_START_LOG2]->alloc(); + if (!addr) { + PERR("Failed to get slab for %u", 1 << msb); + return 0; } - - _pool->free((void *)addr); - } - /** - * Get phys addr - */ - Genode::addr_t phys_addr(void *addr) - { - for (register unsigned i = SLAB_START_LOG2; i <= SLAB_STOP_LOG2; i++) { - Genode::Slab_alloc *slab = _allocator[i - SLAB_START_LOG2]; - - if (!slab->match(addr)) - continue; + _set_at(addr, msb - SLAB_START_LOG2); + addr += sizeof(addr_t); - return slab->phys_addr(addr); + if (align > 2) { + /* save */ + addr_t ptr = addr; + addr_t align_val = (1U << align); + addr_t align_mask = align_val - 2; + /* align */ + addr = (addr + align_val) & ~align_mask; + /* write start address before aligned address */ + _set_at(addr - sizeof(addr_t), ptr); } - /* not found in slabs, try in back-end */ - return _pool->phys_addr(addr); + + if (phys) + *phys = _allocator[msb - SLAB_START_LOG2]->phys_addr(addr); + return (addr_t *)addr; } - - /** - * Allocate aligned memory in slabs - */ - void *dma_pool_alloc(size_t size, int align, Genode::addr_t *dma) + void free(void const *a) { using namespace Genode; + addr_t *addr = (addr_t *)a; - int msb = _dma_pool_slab(size); - addr_t base = (addr_t)_allocator[msb - SLAB_START_LOG2]->alloc(); + unsigned nr = _slab_index(&addr); + _allocator[nr]->free((void *)(addr - 1)); + } - unsigned align_val = (1U << align); - unsigned align_mask = align_val - 1; - - /* make room for pointer */ - addr_t addr = base + sizeof(Genode::addr_t); - - /* align */ - addr = (addr + align_val - 1) & ~align_mask; - addr_t *ptr = (addr_t *)addr - 1; - *ptr = base; - - *dma = phys_addr((void *)addr); - return (void *)addr; + Genode::addr_t phys_addr(void *a) + { + using namespace Genode; + addr_t *addr = (addr_t *)a; + return _allocator[_slab_index(&addr)]->phys_addr((addr_t)a); } /** - * Free memory allocted with 'dma_pool_alloc' + * Belongs given address to this allocator */ - void dma_pool_free(size_t size, void *addr) - { - using namespace Genode; + bool inside(addr_t const addr) const { return (addr > _start) && (addr <= _end); } - int msb = _dma_pool_slab(size); - addr_t base = *((addr_t *)addr - 1); - _allocator[msb - SLAB_START_LOG2]->free((void *)base); + /** + * Cached memory allocator + */ + static Malloc *mem() + { + static Slab_backend_alloc _b(true); + static Malloc _m(&_b, true); + return &_m; + } + + /** + * DMA allocator + */ + static Malloc *dma() + { + static Slab_backend_alloc _b(false); + static Malloc _m(&_b, false); + return &_m; } }; @@ -280,6 +364,11 @@ void mutex_unlock(struct mutex *m) { if (m->lock) dde_kit_lock_unlock( m->lock); void *kmalloc(size_t size, gfp_t flags) { void *addr = flags & GFP_NOIO ? Malloc::dma()->alloc(size) : Malloc::mem()->alloc(size); + + unsigned long a = (unsigned long)addr; + + if (a & 0x3) + PERR("Unaligned kmalloc %lx", a); return addr; } @@ -304,8 +393,11 @@ void *kcalloc(size_t n, size_t size, gfp_t flags) void kfree(const void *p) { - Malloc::mem()->free(p); - Malloc::dma()->free(p); + if (Malloc::mem()->inside((Genode::addr_t)p)) + Malloc::mem()->free(p); + + if (Malloc::dma()->inside((Genode::addr_t)p)) + Malloc::dma()->free(p); } @@ -756,7 +848,7 @@ static Timer::Connection _timer; void udelay(unsigned long usecs) { - _timer.msleep(usecs < 1000 ? 1 : usecs / 1000); + _timer.usleep(usecs); } @@ -807,25 +899,24 @@ void dma_pool_destroy(struct dma_pool *d) void *dma_pool_alloc(struct dma_pool *d, gfp_t f, dma_addr_t *dma) { - return Malloc::dma()->dma_pool_alloc(d->size, d->align, (Genode::addr_t*)dma); + return Malloc::dma()->alloc(d->size, d->align, (Genode::addr_t*)dma); } void dma_pool_free(struct dma_pool *d, void *vaddr, dma_addr_t a) { dde_kit_log(DEBUG_DMA, "free: addr %p, size: %zx", vaddr, d->size); - Malloc::dma()->dma_pool_free(d->size, vaddr); + Malloc::dma()->free(vaddr); } void *dma_alloc_coherent(struct device *, size_t size, dma_addr_t *dma, gfp_t) { - void *addr = Malloc::dma()->alloc(size, PAGE_SHIFT); + void *addr = Malloc::dma()->alloc(size, PAGE_SHIFT, dma); if (!addr) return 0; - *dma = (dma_addr_t)Malloc::dma()->phys_addr(addr); dde_kit_log(DEBUG_DMA, "DMA pool alloc addr: %p size %zx align: %d, phys: %lx", addr, size, PAGE_SHIFT, *dma); return addr; @@ -853,6 +944,10 @@ dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr, { dma_addr_t phys = (dma_addr_t)Malloc::dma()->phys_addr(ptr); + if (phys == ~0UL) + PERR("translation virt->phys %p->%lx failed, return ip %p", ptr, phys, + __builtin_return_address(0)); + dde_kit_log(DEBUG_DMA, "virt: %p phys: %lx", ptr, phys); return phys; } diff --git a/dde_linux/src/lib/usb/nic/nic.cc b/dde_linux/src/lib/usb/nic/nic.cc index 09d743b323..d3249d55d6 100644 --- a/dde_linux/src/lib/usb/nic/nic.cc +++ b/dde_linux/src/lib/usb/nic/nic.cc @@ -20,7 +20,6 @@ #include #include -#include #include #include "signal.h" @@ -69,7 +68,7 @@ class Skb Genode::memset(_free, 0xff, sizeof(_free)); for (unsigned i = 0; i < ENTRIES; i++) - _buf[i].start = (unsigned char *)Genode::Mem::dma()->alloc(BUFFER);; + _buf[i].start = (unsigned char *)kmalloc(BUFFER, GFP_NOIO); } sk_buff *alloc() diff --git a/dde_linux/src/lib/usb/pci_driver.cc b/dde_linux/src/lib/usb/pci_driver.cc index 43697c8d4f..6806e08782 100644 --- a/dde_linux/src/lib/usb/pci_driver.cc +++ b/dde_linux/src/lib/usb/pci_driver.cc @@ -17,8 +17,7 @@ /* Linux includes */ #include - -#include "mem.h" +#include struct bus_type pci_bus_type; @@ -311,10 +310,14 @@ const char *pci_name(const struct pci_dev *pdev) return "dummy"; } -Genode::Ram_dataspace_capability Genode::Mem::alloc_dma_buffer(size_t size) +Genode::Ram_dataspace_capability Backend_memory::alloc(Genode::addr_t size, + bool cached) { using namespace Genode; - Ram_dataspace_capability ram_cap = pci.alloc_dma_buffer(pci_device_cap, - size); - return ram_cap; + + PERR("use it here %u", cached); + if (cached) + return env()->ram_session()->alloc(size, cached); + else + return pci.alloc_dma_buffer(pci_device_cap, size); }