108 lines
2.0 KiB
C++
108 lines
2.0 KiB
C++
/*
|
|
* \brief Capability-selector allocator
|
|
* \author Stefan Kalkowski
|
|
* \date 2010-12-06
|
|
*
|
|
* This is a Fiasco.OC-specific addition to the process enviroment.
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2010-2012 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.
|
|
*/
|
|
|
|
/* Genode includes */
|
|
#include <base/cap_sel_alloc.h>
|
|
#include <base/native_types.h>
|
|
#include <base/printf.h>
|
|
#include <cpu/atomic.h>
|
|
|
|
/* Fiasco.OC includes */
|
|
namespace Fiasco {
|
|
#include <l4/sys/ipc.h>
|
|
#include <l4/sys/consts.h>
|
|
}
|
|
|
|
using namespace Genode;
|
|
|
|
/**
|
|
* First available capability selector for custom use
|
|
*
|
|
* Must be initialized by the startup code
|
|
*/
|
|
static unsigned long __first_free_cap_selector =
|
|
Fiasco::Fiasco_capability::USER_BASE_CAP;
|
|
|
|
/**
|
|
* Low-level lock to protect the allocator
|
|
*
|
|
* We cannot use a normal Genode lock because this lock is used by code
|
|
* executed prior the initialization of Genode.
|
|
*/
|
|
class Alloc_lock
|
|
{
|
|
private:
|
|
|
|
int _state;
|
|
|
|
public:
|
|
|
|
enum State { LOCKED, UNLOCKED };
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
Alloc_lock() : _state(UNLOCKED) {}
|
|
|
|
void lock()
|
|
{
|
|
while (!Genode::cmpxchg(&_state, UNLOCKED, LOCKED))
|
|
Fiasco::l4_ipc_sleep(Fiasco::l4_ipc_timeout(0, 0, 500, 0));
|
|
}
|
|
|
|
void unlock() { _state = UNLOCKED; }
|
|
};
|
|
|
|
|
|
/**
|
|
* Return lock used to protect capability selector allocations
|
|
*/
|
|
static Alloc_lock *alloc_lock()
|
|
{
|
|
static Alloc_lock alloc_lock_inst;
|
|
return &alloc_lock_inst;
|
|
}
|
|
|
|
|
|
addr_t Capability_allocator::alloc(size_t num_caps)
|
|
{
|
|
alloc_lock()->lock();
|
|
int ret_base = _cap_idx;
|
|
_cap_idx += num_caps * Fiasco::L4_CAP_SIZE;
|
|
alloc_lock()->unlock();
|
|
return ret_base;
|
|
}
|
|
|
|
|
|
void Capability_allocator::free(addr_t cap, size_t num_caps_log2)
|
|
{
|
|
// PWRN("Not yet implemented!");
|
|
}
|
|
|
|
|
|
Capability_allocator::Capability_allocator()
|
|
: _cap_idx(__first_free_cap_selector)
|
|
{
|
|
/* initialize lock */
|
|
alloc_lock();
|
|
}
|
|
|
|
|
|
Capability_allocator* Capability_allocator::allocator()
|
|
{
|
|
static Capability_allocator inst;
|
|
return &inst;
|
|
}
|