mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-29 13:44:26 +00:00
Io_mem_session, fix #128
Free unaligned ranges correctly in range allocator
This commit is contained in:
parent
a9152ff412
commit
b6e355b841
@ -40,13 +40,18 @@ namespace Genode {
|
|||||||
addr_t phys_addr;
|
addr_t phys_addr;
|
||||||
bool write_combined;
|
bool write_combined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base address of request used for freeing mem-ranges
|
||||||
|
*/
|
||||||
|
addr_t req_base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
*
|
*
|
||||||
* This constructor enables Dataspace_attr objects to be
|
* This constructor enables Dataspace_attr objects to be
|
||||||
* returned from the '_prepare_io_mem' function.
|
* returned from the '_prepare_io_mem' function.
|
||||||
*/
|
*/
|
||||||
Dataspace_attr() { }
|
Dataspace_attr() : size(0) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@ -54,24 +59,28 @@ namespace Genode {
|
|||||||
* An invalid dataspace is represented by setting all
|
* An invalid dataspace is represented by setting all
|
||||||
* arguments to zero.
|
* arguments to zero.
|
||||||
*/
|
*/
|
||||||
Dataspace_attr(size_t s, addr_t cla, addr_t pa, bool write_combined):
|
Dataspace_attr(size_t s, addr_t cla, addr_t pa, bool write_combined,
|
||||||
size(s), core_local_addr(cla), phys_addr(pa) { }
|
addr_t req_base)
|
||||||
|
:
|
||||||
|
size(s), core_local_addr(cla), phys_addr(pa), req_base(req_base) { }
|
||||||
|
};
|
||||||
|
|
||||||
} ds_attr;
|
struct Io_dataspace_component : Dataspace_component
|
||||||
|
|
||||||
class Io_dataspace_component : public Dataspace_component
|
|
||||||
{
|
{
|
||||||
public:
|
addr_t req_base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
Io_dataspace_component(Dataspace_attr da)
|
Io_dataspace_component(Dataspace_attr da)
|
||||||
: Dataspace_component(da.size, da.core_local_addr,
|
:
|
||||||
da.phys_addr, da.write_combined,
|
Dataspace_component(da.size, da.core_local_addr,
|
||||||
true) { }
|
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;
|
Range_allocator *_io_mem_alloc;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include <root/root.h>
|
#include <root/root.h>
|
||||||
#include <dataspace_component.h>
|
#include <dataspace_component.h>
|
||||||
#include <io_mem_session_component.h>
|
#include <io_mem_session_component.h>
|
||||||
|
#include <base/allocator_avl.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
@ -47,18 +47,18 @@ Io_mem_session_component::_prepare_io_mem(const char *args,
|
|||||||
int ret;
|
int ret;
|
||||||
if ((ret = ram_alloc->remove_range(base, size))) {
|
if ((ret = ram_alloc->remove_range(base, size))) {
|
||||||
PERR("I/O memory [%lx,%lx) used by RAM allocator (%d)", base, base + size, ret);
|
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 */
|
/* allocate region */
|
||||||
switch (_io_mem_alloc->alloc_addr(req_size, req_base)) {
|
switch (_io_mem_alloc->alloc_addr(req_size, req_base)) {
|
||||||
case Range_allocator::RANGE_CONFLICT:
|
case Range_allocator::RANGE_CONFLICT:
|
||||||
PERR("I/O memory [%lx,%lx) not available", base, base + size);
|
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:
|
case Range_allocator::OUT_OF_METADATA:
|
||||||
PERR("I/O memory allocator ran out of meta data");
|
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;
|
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,
|
base, base + size, local_addr, local_addr + size,
|
||||||
_write_combined ? " (write-combined)" : "");
|
_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()
|
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 */
|
/* dissolve IO_MEM dataspace from service entry point */
|
||||||
_ds_ep->dissolve(&_ds);
|
_ds_ep->dissolve(&_ds);
|
||||||
|
|
||||||
@ -110,5 +112,5 @@ Io_mem_session_component::~Io_mem_session_component()
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* free region in IO_MEM allocator */
|
/* free region in IO_MEM allocator */
|
||||||
_io_mem_alloc->free(reinterpret_cast<void *>(_ds.phys_addr()));
|
_io_mem_alloc->free(reinterpret_cast<void *>(_ds.req_base));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user