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);
}