From b6e355b8417af3e9205cae0529b52ec30a33da0f Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Sat, 25 Feb 2012 21:21:57 +0100 Subject: [PATCH] Io_mem_session, fix #128 Free unaligned ranges correctly in range allocator --- .../core/include/io_mem_session_component.h | 39 ++++++++++++------- base/src/core/io_mem_session_component.cc | 14 ++++--- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/base/src/core/include/io_mem_session_component.h b/base/src/core/include/io_mem_session_component.h index a3c4edd1f5..8207df7dce 100644 --- a/base/src/core/include/io_mem_session_component.h +++ b/base/src/core/include/io_mem_session_component.h @@ -40,13 +40,18 @@ namespace Genode { addr_t phys_addr; bool write_combined; + /** + * Base address of request used for freeing mem-ranges + */ + addr_t req_base; + /** * Default constructor * * This constructor enables Dataspace_attr objects to be * returned from the '_prepare_io_mem' function. */ - Dataspace_attr() { } + Dataspace_attr() : size(0) { } /** * Constructor @@ -54,24 +59,28 @@ namespace Genode { * An invalid dataspace is represented by setting all * arguments to zero. */ - Dataspace_attr(size_t s, addr_t cla, addr_t pa, bool write_combined): - size(s), core_local_addr(cla), phys_addr(pa) { } + Dataspace_attr(size_t s, addr_t cla, addr_t pa, bool write_combined, + addr_t req_base) + : + size(s), core_local_addr(cla), phys_addr(pa), req_base(req_base) { } + }; - } ds_attr; - - class Io_dataspace_component : public Dataspace_component + struct Io_dataspace_component : Dataspace_component { - public: + addr_t req_base; - /** - * Constructor - */ - Io_dataspace_component(Dataspace_attr da) - : Dataspace_component(da.size, da.core_local_addr, - da.phys_addr, da.write_combined, - true) { } + /** + * Constructor + */ + Io_dataspace_component(Dataspace_attr da) + : + Dataspace_component(da.size, da.core_local_addr, + da.phys_addr, da.write_combined, + true), + req_base(da.req_base) { } - bool valid() { return size() != 0; } + + bool valid() { return size() != 0; } }; Range_allocator *_io_mem_alloc; diff --git a/base/src/core/io_mem_session_component.cc b/base/src/core/io_mem_session_component.cc index 98dd157718..182bafb64e 100644 --- a/base/src/core/io_mem_session_component.cc +++ b/base/src/core/io_mem_session_component.cc @@ -16,7 +16,7 @@ #include #include #include - +#include #include "util.h" using namespace Genode; @@ -47,18 +47,18 @@ Io_mem_session_component::_prepare_io_mem(const char *args, int ret; if ((ret = ram_alloc->remove_range(base, size))) { PERR("I/O memory [%lx,%lx) used by RAM allocator (%d)", base, base + size, ret); - return Dataspace_attr(0, 0, 0, 0); + return Dataspace_attr(); } /* allocate region */ switch (_io_mem_alloc->alloc_addr(req_size, req_base)) { case Range_allocator::RANGE_CONFLICT: PERR("I/O memory [%lx,%lx) not available", base, base + size); - return Dataspace_attr(0, 0, 0, 0); + return Dataspace_attr(); case Range_allocator::OUT_OF_METADATA: PERR("I/O memory allocator ran out of meta data"); - return Dataspace_attr(0, 0, 0, 0); + return Dataspace_attr(); case Range_allocator::ALLOC_OK: break; } @@ -71,7 +71,7 @@ Io_mem_session_component::_prepare_io_mem(const char *args, base, base + size, local_addr, local_addr + size, _write_combined ? " (write-combined)" : ""); - return Dataspace_attr(size, local_addr, base, _write_combined); + return Dataspace_attr(size, local_addr, base, _write_combined, req_base); } @@ -97,6 +97,8 @@ Io_mem_session_component::Io_mem_session_component(Range_allocator *io_mem_alloc Io_mem_session_component::~Io_mem_session_component() { + if (verbose) + PDBG("I/O mem free [%lx,%lx)", _ds.phys_addr(), _ds.phys_addr() + _ds.size()); /* dissolve IO_MEM dataspace from service entry point */ _ds_ep->dissolve(&_ds); @@ -110,5 +112,5 @@ Io_mem_session_component::~Io_mem_session_component() */ /* free region in IO_MEM allocator */ - _io_mem_alloc->free(reinterpret_cast(_ds.phys_addr())); + _io_mem_alloc->free(reinterpret_cast(_ds.req_base)); }