mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 17:52:52 +00:00
base-okl4: coding style
This commit is contained in:
parent
abd688097a
commit
9189342b77
@ -17,4 +17,7 @@
|
||||
/* base-internal includes */
|
||||
#include <base/internal/okl4.h>
|
||||
|
||||
void Genode::Core_log::out(char const c) { Okl4::L4_KDB_PrintChar(c); }
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Core_log::out(char const c) { Okl4::L4_KDB_PrintChar(c); }
|
||||
|
@ -23,161 +23,162 @@
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Mapping
|
||||
{
|
||||
private:
|
||||
|
||||
addr_t _phys_addr { 0 };
|
||||
Okl4::L4_Fpage_t _fpage { };
|
||||
Okl4::L4_PhysDesc_t _phys_desc { };
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Mapping(addr_t dst_addr, addr_t src_addr,
|
||||
Cache_attribute cacheability, bool io_mem,
|
||||
unsigned l2size, bool rw, bool executable);
|
||||
|
||||
/**
|
||||
* Construct invalid mapping
|
||||
*/
|
||||
Mapping();
|
||||
|
||||
/**
|
||||
* Return flexpage describing the virtual destination address
|
||||
*/
|
||||
Okl4::L4_Fpage_t fpage() const { return _fpage; }
|
||||
|
||||
/**
|
||||
* Return physical-memory descriptor describing the source location
|
||||
*/
|
||||
Okl4::L4_PhysDesc_t phys_desc() const { return _phys_desc; }
|
||||
|
||||
/**
|
||||
* Prepare map operation
|
||||
*
|
||||
* On OKL4, we do not need to map a page core-locally to be able to
|
||||
* map it into another address space. Therefore, we can leave this
|
||||
* function blank.
|
||||
*/
|
||||
void prepare_map_operation() { }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Special paging server class
|
||||
*/
|
||||
class Ipc_pager
|
||||
{
|
||||
private:
|
||||
|
||||
Okl4::L4_MsgTag_t _faulter_tag { 0 }; /* fault flags */
|
||||
Okl4::L4_ThreadId_t _last { 0 }; /* faulted thread */
|
||||
Okl4::L4_Word_t _last_space { 0 }; /* space of faulted thread */
|
||||
Okl4::L4_Word_t _fault_addr { 0 }; /* page-fault address */
|
||||
Okl4::L4_Word_t _fault_ip { 0 }; /* instruction pointer of faulter */
|
||||
Mapping _reply_mapping { }; /* page-fault answer */
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Wait for short-message (register) IPC -- fault
|
||||
*/
|
||||
void _wait();
|
||||
|
||||
/**
|
||||
* Send short flex page and
|
||||
* wait for next short-message (register) IPC -- fault
|
||||
*/
|
||||
void _reply_and_wait();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Wait for a new fault received as short message IPC
|
||||
*/
|
||||
void wait_for_fault();
|
||||
|
||||
/**
|
||||
* Reply current fault and wait for a new one
|
||||
*
|
||||
* Send short flex page and wait for next short-message (register)
|
||||
* IPC -- pagefault
|
||||
*/
|
||||
void reply_and_wait_for_fault();
|
||||
|
||||
/**
|
||||
* Request instruction pointer of current fault
|
||||
*/
|
||||
addr_t fault_ip() { return _fault_ip; }
|
||||
|
||||
/**
|
||||
* Request fault address of current fault
|
||||
*/
|
||||
addr_t fault_addr() { return _fault_addr & ~3; }
|
||||
|
||||
/**
|
||||
* Set parameters for next reply
|
||||
*/
|
||||
void set_reply_mapping(Mapping m) { _reply_mapping = m; }
|
||||
|
||||
/**
|
||||
* Set destination for next reply
|
||||
*/
|
||||
void set_reply_dst(Native_capability pager_object) {
|
||||
_last.raw = pager_object.local_name(); }
|
||||
|
||||
/**
|
||||
* Answer call without sending a flex-page mapping
|
||||
*
|
||||
* This function is used to acknowledge local calls from one of
|
||||
* core's region-manager sessions.
|
||||
*/
|
||||
void acknowledge_wakeup();
|
||||
|
||||
/**
|
||||
* Returns true if the last request was send from a core thread
|
||||
*/
|
||||
bool request_from_core() const
|
||||
{
|
||||
enum { CORE_SPACE = 0 };
|
||||
return _last_space == CORE_SPACE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return badge for faulting thread
|
||||
*
|
||||
* Because OKL4 has no server-defined badges for fault messages, we
|
||||
* interpret the sender ID as badge.
|
||||
*/
|
||||
unsigned long badge() const { return _last.raw; }
|
||||
|
||||
/**
|
||||
* Return true if last fault was a write fault
|
||||
*/
|
||||
bool write_fault() const { return L4_Label(_faulter_tag) & 2; }
|
||||
|
||||
/**
|
||||
* Return true if last fault was a executable fault
|
||||
*/
|
||||
bool exec_fault() const { return false; }
|
||||
|
||||
/**
|
||||
* Return true if last fault was an exception
|
||||
*/
|
||||
bool exception() const
|
||||
{
|
||||
/*
|
||||
* A page-fault message has one of the op bits (lower 3 bits of the
|
||||
* label) set. If those bits are zero, we got an exception message.
|
||||
* If the label is zero, we got an IPC wakeup message from within
|
||||
* core.
|
||||
*/
|
||||
return L4_Label(_faulter_tag) && (L4_Label(_faulter_tag) & 0xf) == 0;
|
||||
}
|
||||
};
|
||||
class Mapping;
|
||||
class Ipc_pager;
|
||||
}
|
||||
|
||||
|
||||
class Genode::Mapping
|
||||
{
|
||||
private:
|
||||
|
||||
addr_t _phys_addr { 0 };
|
||||
Okl4::L4_Fpage_t _fpage { };
|
||||
Okl4::L4_PhysDesc_t _phys_desc { };
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Mapping(addr_t dst_addr, addr_t src_addr,
|
||||
Cache_attribute cacheability, bool io_mem,
|
||||
unsigned l2size, bool rw, bool executable);
|
||||
|
||||
/**
|
||||
* Construct invalid mapping
|
||||
*/
|
||||
Mapping();
|
||||
|
||||
/**
|
||||
* Return flexpage describing the virtual destination address
|
||||
*/
|
||||
Okl4::L4_Fpage_t fpage() const { return _fpage; }
|
||||
|
||||
/**
|
||||
* Return physical-memory descriptor describing the source location
|
||||
*/
|
||||
Okl4::L4_PhysDesc_t phys_desc() const { return _phys_desc; }
|
||||
|
||||
/**
|
||||
* Prepare map operation
|
||||
*
|
||||
* On OKL4, we do not need to map a page core-locally to be able to
|
||||
* map it into another address space. Therefore, we can leave this
|
||||
* function blank.
|
||||
*/
|
||||
void prepare_map_operation() { }
|
||||
};
|
||||
|
||||
|
||||
class Genode::Ipc_pager
|
||||
{
|
||||
private:
|
||||
|
||||
Okl4::L4_MsgTag_t _faulter_tag { 0 }; /* fault flags */
|
||||
Okl4::L4_ThreadId_t _last { 0 }; /* faulted thread */
|
||||
Okl4::L4_Word_t _last_space { 0 }; /* space of faulted thread */
|
||||
Okl4::L4_Word_t _fault_addr { 0 }; /* page-fault address */
|
||||
Okl4::L4_Word_t _fault_ip { 0 }; /* instruction pointer of faulter */
|
||||
Mapping _reply_mapping { }; /* page-fault answer */
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Wait for short-message (register) IPC -- fault
|
||||
*/
|
||||
void _wait();
|
||||
|
||||
/**
|
||||
* Send short flex page and
|
||||
* wait for next short-message (register) IPC -- fault
|
||||
*/
|
||||
void _reply_and_wait();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Wait for a new fault received as short message IPC
|
||||
*/
|
||||
void wait_for_fault();
|
||||
|
||||
/**
|
||||
* Reply current fault and wait for a new one
|
||||
*
|
||||
* Send short flex page and wait for next short-message (register)
|
||||
* IPC -- pagefault
|
||||
*/
|
||||
void reply_and_wait_for_fault();
|
||||
|
||||
/**
|
||||
* Request instruction pointer of current fault
|
||||
*/
|
||||
addr_t fault_ip() { return _fault_ip; }
|
||||
|
||||
/**
|
||||
* Request fault address of current fault
|
||||
*/
|
||||
addr_t fault_addr() { return _fault_addr & ~3; }
|
||||
|
||||
/**
|
||||
* Set parameters for next reply
|
||||
*/
|
||||
void set_reply_mapping(Mapping m) { _reply_mapping = m; }
|
||||
|
||||
/**
|
||||
* Set destination for next reply
|
||||
*/
|
||||
void set_reply_dst(Native_capability pager_object) {
|
||||
_last.raw = pager_object.local_name(); }
|
||||
|
||||
/**
|
||||
* Answer call without sending a flex-page mapping
|
||||
*
|
||||
* This function is used to acknowledge local calls from one of
|
||||
* core's region-manager sessions.
|
||||
*/
|
||||
void acknowledge_wakeup();
|
||||
|
||||
/**
|
||||
* Returns true if the last request was send from a core thread
|
||||
*/
|
||||
bool request_from_core() const
|
||||
{
|
||||
enum { CORE_SPACE = 0 };
|
||||
return _last_space == CORE_SPACE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return badge for faulting thread
|
||||
*
|
||||
* Because OKL4 has no server-defined badges for fault messages, we
|
||||
* interpret the sender ID as badge.
|
||||
*/
|
||||
unsigned long badge() const { return _last.raw; }
|
||||
|
||||
/**
|
||||
* Return true if last fault was a write fault
|
||||
*/
|
||||
bool write_fault() const { return L4_Label(_faulter_tag) & 2; }
|
||||
|
||||
/**
|
||||
* Return true if last fault was a executable fault
|
||||
*/
|
||||
bool exec_fault() const { return false; }
|
||||
|
||||
/**
|
||||
* Return true if last fault was an exception
|
||||
*/
|
||||
bool exception() const
|
||||
{
|
||||
/*
|
||||
* A page-fault message has one of the op bits (lower 3 bits of the
|
||||
* label) set. If those bits are zero, we got an exception message.
|
||||
* If the label is zero, we got an IPC wakeup message from within
|
||||
* core.
|
||||
*/
|
||||
return L4_Label(_faulter_tag) && (L4_Label(_faulter_tag) & 0xf) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _CORE__INCLUDE__IPC_PAGER_H_ */
|
||||
|
@ -32,124 +32,124 @@ namespace Okl4 { extern "C" {
|
||||
#include <bootinfo/bootinfo.h>
|
||||
} }
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Platform : public Platform_generic
|
||||
{
|
||||
private:
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Platform(Platform const &);
|
||||
Platform &operator = (Platform const &);
|
||||
|
||||
using Rom_slab = Tslab<Rom_module, get_page_size()>;
|
||||
using Thread_slab = Tslab<Platform_thread, get_page_size()>;
|
||||
|
||||
Platform_pd *_core_pd = nullptr; /* core protection domain */
|
||||
Platform_thread *_core_pager = nullptr; /* pager for core threads */
|
||||
Core_mem_allocator _core_mem_alloc { }; /* core-accessible memory */
|
||||
Phys_allocator _io_mem_alloc; /* MMIO allocator */
|
||||
Phys_allocator _io_port_alloc; /* I/O port allocator */
|
||||
Phys_allocator _irq_alloc; /* IRQ allocator */
|
||||
Rom_slab _rom_slab; /* slab for rom modules */
|
||||
Rom_fs _rom_fs { }; /* ROM file system */
|
||||
Thread_slab _thread_slab; /* slab for platform threads */
|
||||
|
||||
/*
|
||||
* Virtual-memory range for non-core address spaces.
|
||||
* The virtual memory layout of core is maintained in
|
||||
* '_core_mem_alloc.virt_alloc()'.
|
||||
*/
|
||||
addr_t _vm_start = 0;
|
||||
size_t _vm_size = 0;
|
||||
|
||||
/*
|
||||
* Start of address range used for the UTCBs
|
||||
*/
|
||||
addr_t _utcb_base = 0;
|
||||
|
||||
void _init_rom_modules();
|
||||
|
||||
addr_t _rom_module_phys(addr_t virt) { return virt; }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform();
|
||||
|
||||
/**
|
||||
* Accessor for core pd object
|
||||
*/
|
||||
Platform_pd &core_pd()
|
||||
{
|
||||
if (_core_pd)
|
||||
return *_core_pd;
|
||||
|
||||
ASSERT_NEVER_CALLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for core pager thread object
|
||||
*/
|
||||
Platform_thread &core_pager()
|
||||
{
|
||||
if (_core_pager)
|
||||
return *_core_pager;
|
||||
|
||||
ASSERT_NEVER_CALLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for platform thread object slab allocator
|
||||
*/
|
||||
Thread_slab &thread_slab() { return _thread_slab; }
|
||||
|
||||
/**********************************************
|
||||
** Callbacks used for parsing the boot info **
|
||||
**********************************************/
|
||||
|
||||
static int bi_init_mem(Okl4::uintptr_t, Okl4::uintptr_t,
|
||||
Okl4::uintptr_t, Okl4::uintptr_t,
|
||||
const Okl4::bi_user_data_t *);
|
||||
|
||||
static int bi_add_virt_mem(Okl4::bi_name_t,
|
||||
Okl4::uintptr_t, Okl4::uintptr_t,
|
||||
const Okl4::bi_user_data_t *);
|
||||
|
||||
static int bi_add_phys_mem(Okl4::bi_name_t,
|
||||
Okl4::uintptr_t, Okl4::uintptr_t,
|
||||
const Okl4::bi_user_data_t *);
|
||||
|
||||
/********************************
|
||||
** Generic platform interface **
|
||||
********************************/
|
||||
|
||||
Range_allocator &ram_alloc() override { return _core_mem_alloc.phys_alloc(); }
|
||||
Range_allocator &io_mem_alloc() override { return _io_mem_alloc; }
|
||||
Range_allocator &io_port_alloc() override { return _io_port_alloc; }
|
||||
Range_allocator &irq_alloc() override { return _irq_alloc; }
|
||||
Range_allocator ®ion_alloc() override { return _core_mem_alloc.virt_alloc(); }
|
||||
Range_allocator &core_mem_alloc() override { return _core_mem_alloc; }
|
||||
addr_t vm_start() const override { return _vm_start; }
|
||||
size_t vm_size() const override { return _vm_size; }
|
||||
Rom_fs &rom_fs() override { return _rom_fs; }
|
||||
size_t max_caps() const override { return Capability_space::max_caps(); }
|
||||
|
||||
void wait_for_exit() override;
|
||||
|
||||
bool supports_direct_unmap() const override { return true; }
|
||||
namespace Genode { class Platform; }
|
||||
|
||||
|
||||
/**************************************
|
||||
** OKL4-specific platform interface **
|
||||
**************************************/
|
||||
class Genode::Platform : public Platform_generic
|
||||
{
|
||||
private:
|
||||
|
||||
addr_t utcb_base() { return _utcb_base; }
|
||||
};
|
||||
}
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Platform(Platform const &);
|
||||
Platform &operator = (Platform const &);
|
||||
|
||||
using Rom_slab = Tslab<Rom_module, get_page_size()>;
|
||||
using Thread_slab = Tslab<Platform_thread, get_page_size()>;
|
||||
|
||||
Platform_pd *_core_pd = nullptr; /* core protection domain */
|
||||
Platform_thread *_core_pager = nullptr; /* pager for core threads */
|
||||
Core_mem_allocator _core_mem_alloc { }; /* core-accessible memory */
|
||||
Phys_allocator _io_mem_alloc; /* MMIO allocator */
|
||||
Phys_allocator _io_port_alloc; /* I/O port allocator */
|
||||
Phys_allocator _irq_alloc; /* IRQ allocator */
|
||||
Rom_slab _rom_slab; /* slab for rom modules */
|
||||
Rom_fs _rom_fs { }; /* ROM file system */
|
||||
Thread_slab _thread_slab; /* slab for platform threads */
|
||||
|
||||
/*
|
||||
* Virtual-memory range for non-core address spaces.
|
||||
* The virtual memory layout of core is maintained in
|
||||
* '_core_mem_alloc.virt_alloc()'.
|
||||
*/
|
||||
addr_t _vm_start = 0;
|
||||
size_t _vm_size = 0;
|
||||
|
||||
/*
|
||||
* Start of address range used for the UTCBs
|
||||
*/
|
||||
addr_t _utcb_base = 0;
|
||||
|
||||
void _init_rom_modules();
|
||||
|
||||
addr_t _rom_module_phys(addr_t virt) { return virt; }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform();
|
||||
|
||||
/**
|
||||
* Accessor for core pd object
|
||||
*/
|
||||
Platform_pd &core_pd()
|
||||
{
|
||||
if (_core_pd)
|
||||
return *_core_pd;
|
||||
|
||||
ASSERT_NEVER_CALLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for core pager thread object
|
||||
*/
|
||||
Platform_thread &core_pager()
|
||||
{
|
||||
if (_core_pager)
|
||||
return *_core_pager;
|
||||
|
||||
ASSERT_NEVER_CALLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for platform thread object slab allocator
|
||||
*/
|
||||
Thread_slab &thread_slab() { return _thread_slab; }
|
||||
|
||||
/**********************************************
|
||||
** Callbacks used for parsing the boot info **
|
||||
**********************************************/
|
||||
|
||||
static int bi_init_mem(Okl4::uintptr_t, Okl4::uintptr_t,
|
||||
Okl4::uintptr_t, Okl4::uintptr_t,
|
||||
const Okl4::bi_user_data_t *);
|
||||
|
||||
static int bi_add_virt_mem(Okl4::bi_name_t,
|
||||
Okl4::uintptr_t, Okl4::uintptr_t,
|
||||
const Okl4::bi_user_data_t *);
|
||||
|
||||
static int bi_add_phys_mem(Okl4::bi_name_t,
|
||||
Okl4::uintptr_t, Okl4::uintptr_t,
|
||||
const Okl4::bi_user_data_t *);
|
||||
|
||||
/********************************
|
||||
** Generic platform interface **
|
||||
********************************/
|
||||
|
||||
Range_allocator &ram_alloc() override { return _core_mem_alloc.phys_alloc(); }
|
||||
Range_allocator &io_mem_alloc() override { return _io_mem_alloc; }
|
||||
Range_allocator &io_port_alloc() override { return _io_port_alloc; }
|
||||
Range_allocator &irq_alloc() override { return _irq_alloc; }
|
||||
Range_allocator ®ion_alloc() override { return _core_mem_alloc.virt_alloc(); }
|
||||
Range_allocator &core_mem_alloc() override { return _core_mem_alloc; }
|
||||
addr_t vm_start() const override { return _vm_start; }
|
||||
size_t vm_size() const override { return _vm_size; }
|
||||
Rom_fs &rom_fs() override { return _rom_fs; }
|
||||
size_t max_caps() const override { return Capability_space::max_caps(); }
|
||||
|
||||
void wait_for_exit() override;
|
||||
|
||||
bool supports_direct_unmap() const override { return true; }
|
||||
|
||||
|
||||
/**************************************
|
||||
** OKL4-specific platform interface **
|
||||
**************************************/
|
||||
|
||||
addr_t utcb_base() { return _utcb_base; }
|
||||
};
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_H_ */
|
||||
|
@ -35,177 +35,180 @@ namespace Genode {
|
||||
}
|
||||
|
||||
class Platform_thread;
|
||||
class Platform_pd : public Address_space
|
||||
{
|
||||
private:
|
||||
|
||||
friend class Platform_thread;
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Platform_pd(Platform_pd const &);
|
||||
Platform_pd &operator = (Platform_pd const &);
|
||||
|
||||
enum { PD_INVALID = -1,
|
||||
PD_FIRST = 0,
|
||||
PD_MAX = (1 << Thread_id_bits::PD) - 1,
|
||||
THREAD_MAX = (1 << Thread_id_bits::THREAD) - 1 };
|
||||
|
||||
unsigned _pd_id = PD_INVALID;
|
||||
|
||||
Platform_thread *_space_pager = nullptr;
|
||||
|
||||
/**
|
||||
* Manually construct L4 thread ID from its components
|
||||
*/
|
||||
static Okl4::L4_ThreadId_t make_l4_id(unsigned space_no,
|
||||
unsigned thread_no)
|
||||
{
|
||||
/*
|
||||
* On OKL4, version must be set to 1
|
||||
*/
|
||||
return Okl4::L4_GlobalId((space_no << Thread_id_bits::THREAD) | thread_no, 1);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************
|
||||
** Threads of this protection domain object **
|
||||
**********************************************/
|
||||
|
||||
Platform_thread *_threads[THREAD_MAX];
|
||||
|
||||
/**
|
||||
* Initialize thread allocator
|
||||
*/
|
||||
void _init_threads();
|
||||
|
||||
/**
|
||||
* Thread iteration for one task
|
||||
*/
|
||||
Platform_thread *_next_thread();
|
||||
|
||||
/**
|
||||
* Thread allocation
|
||||
*
|
||||
* Again a special case for Core thread0.
|
||||
*/
|
||||
int _alloc_thread(int thread_id, Platform_thread &thread);
|
||||
|
||||
/**
|
||||
* Thread deallocation
|
||||
*
|
||||
* No special case for Core thread0 here - we just never call it.
|
||||
*/
|
||||
void _free_thread(int thread_id);
|
||||
|
||||
|
||||
/******************
|
||||
** PD allocator **
|
||||
******************/
|
||||
|
||||
struct Pd_alloc
|
||||
{
|
||||
unsigned reserved : 1;
|
||||
unsigned free : 1;
|
||||
|
||||
Pd_alloc(bool r, bool f)
|
||||
: reserved(r), free(f) { }
|
||||
|
||||
Pd_alloc() : reserved(0), free(0) { }
|
||||
};
|
||||
|
||||
static Pd_alloc *_pds()
|
||||
{
|
||||
static Pd_alloc static_pds[PD_MAX + 1];
|
||||
return static_pds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Protection-domain creation
|
||||
*
|
||||
* The syscall parameter propagates if any L4 kernel function
|
||||
* should be used. We need the special case for the Core startup.
|
||||
*/
|
||||
void _create_pd(bool syscall);
|
||||
|
||||
/**
|
||||
* Protection domain destruction
|
||||
*
|
||||
* No special case for Core here - we just never call it.
|
||||
*/
|
||||
void _destroy_pd();
|
||||
|
||||
/**
|
||||
* Protection domain allocation
|
||||
*/
|
||||
int _alloc_pd();
|
||||
|
||||
/**
|
||||
* Protection domain deallocation
|
||||
*
|
||||
* No special case for Core here - we just never call it.
|
||||
*/
|
||||
void _free_pd();
|
||||
|
||||
/**
|
||||
* Setup UTCB area
|
||||
*/
|
||||
void _setup_address_space();
|
||||
|
||||
|
||||
/***************
|
||||
** Debugging **
|
||||
***************/
|
||||
|
||||
void _debug_log_pds(void);
|
||||
void _debug_log_threads(void);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructors
|
||||
*/
|
||||
Platform_pd(bool core);
|
||||
Platform_pd(Allocator &, char const *);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Platform_pd();
|
||||
|
||||
/**
|
||||
* Bind thread to protection domain
|
||||
*
|
||||
* This function allocates the physical L4 thread ID.
|
||||
*/
|
||||
bool bind_thread(Platform_thread &thread);
|
||||
|
||||
/**
|
||||
* Unbind thread from protection domain
|
||||
*
|
||||
* Free the thread's slot and update thread object.
|
||||
*/
|
||||
void unbind_thread(Platform_thread &thread);
|
||||
|
||||
/**
|
||||
* Assign parent interface to protection domain
|
||||
*/
|
||||
void assign_parent(Native_capability) { }
|
||||
|
||||
Platform_thread* space_pager() const { return _space_pager; }
|
||||
|
||||
void space_pager(Platform_thread &pd);
|
||||
|
||||
int pd_id() const { return _pd_id; }
|
||||
|
||||
|
||||
/*****************************
|
||||
** Address-space interface **
|
||||
*****************************/
|
||||
|
||||
void flush(addr_t, size_t, Core_local_addr) override;
|
||||
};
|
||||
class Platform_pd;
|
||||
}
|
||||
|
||||
|
||||
class Genode::Platform_pd : public Address_space
|
||||
{
|
||||
private:
|
||||
|
||||
friend class Platform_thread;
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Platform_pd(Platform_pd const &);
|
||||
Platform_pd &operator = (Platform_pd const &);
|
||||
|
||||
enum { PD_INVALID = -1,
|
||||
PD_FIRST = 0,
|
||||
PD_MAX = (1 << Thread_id_bits::PD) - 1,
|
||||
THREAD_MAX = (1 << Thread_id_bits::THREAD) - 1 };
|
||||
|
||||
unsigned _pd_id = PD_INVALID;
|
||||
|
||||
Platform_thread *_space_pager = nullptr;
|
||||
|
||||
/**
|
||||
* Manually construct L4 thread ID from its components
|
||||
*/
|
||||
static Okl4::L4_ThreadId_t make_l4_id(unsigned space_no,
|
||||
unsigned thread_no)
|
||||
{
|
||||
/*
|
||||
* On OKL4, version must be set to 1
|
||||
*/
|
||||
return Okl4::L4_GlobalId((space_no << Thread_id_bits::THREAD) | thread_no, 1);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************
|
||||
** Threads of this protection domain object **
|
||||
**********************************************/
|
||||
|
||||
Platform_thread *_threads[THREAD_MAX];
|
||||
|
||||
/**
|
||||
* Initialize thread allocator
|
||||
*/
|
||||
void _init_threads();
|
||||
|
||||
/**
|
||||
* Thread iteration for one task
|
||||
*/
|
||||
Platform_thread *_next_thread();
|
||||
|
||||
/**
|
||||
* Thread allocation
|
||||
*
|
||||
* Again a special case for Core thread0.
|
||||
*/
|
||||
int _alloc_thread(int thread_id, Platform_thread &thread);
|
||||
|
||||
/**
|
||||
* Thread deallocation
|
||||
*
|
||||
* No special case for Core thread0 here - we just never call it.
|
||||
*/
|
||||
void _free_thread(int thread_id);
|
||||
|
||||
|
||||
/******************
|
||||
** PD allocator **
|
||||
******************/
|
||||
|
||||
struct Pd_alloc
|
||||
{
|
||||
unsigned reserved : 1;
|
||||
unsigned free : 1;
|
||||
|
||||
Pd_alloc(bool r, bool f)
|
||||
: reserved(r), free(f) { }
|
||||
|
||||
Pd_alloc() : reserved(0), free(0) { }
|
||||
};
|
||||
|
||||
static Pd_alloc *_pds()
|
||||
{
|
||||
static Pd_alloc static_pds[PD_MAX + 1];
|
||||
return static_pds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Protection-domain creation
|
||||
*
|
||||
* The syscall parameter propagates if any L4 kernel function
|
||||
* should be used. We need the special case for the Core startup.
|
||||
*/
|
||||
void _create_pd(bool syscall);
|
||||
|
||||
/**
|
||||
* Protection domain destruction
|
||||
*
|
||||
* No special case for Core here - we just never call it.
|
||||
*/
|
||||
void _destroy_pd();
|
||||
|
||||
/**
|
||||
* Protection domain allocation
|
||||
*/
|
||||
int _alloc_pd();
|
||||
|
||||
/**
|
||||
* Protection domain deallocation
|
||||
*
|
||||
* No special case for Core here - we just never call it.
|
||||
*/
|
||||
void _free_pd();
|
||||
|
||||
/**
|
||||
* Setup UTCB area
|
||||
*/
|
||||
void _setup_address_space();
|
||||
|
||||
|
||||
/***************
|
||||
** Debugging **
|
||||
***************/
|
||||
|
||||
void _debug_log_pds(void);
|
||||
void _debug_log_threads(void);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructors
|
||||
*/
|
||||
Platform_pd(bool core);
|
||||
Platform_pd(Allocator &, char const *);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Platform_pd();
|
||||
|
||||
/**
|
||||
* Bind thread to protection domain
|
||||
*
|
||||
* This function allocates the physical L4 thread ID.
|
||||
*/
|
||||
bool bind_thread(Platform_thread &thread);
|
||||
|
||||
/**
|
||||
* Unbind thread from protection domain
|
||||
*
|
||||
* Free the thread's slot and update thread object.
|
||||
*/
|
||||
void unbind_thread(Platform_thread &thread);
|
||||
|
||||
/**
|
||||
* Assign parent interface to protection domain
|
||||
*/
|
||||
void assign_parent(Native_capability) { }
|
||||
|
||||
Platform_thread* space_pager() const { return _space_pager; }
|
||||
|
||||
void space_pager(Platform_thread &pd);
|
||||
|
||||
int pd_id() const { return _pd_id; }
|
||||
|
||||
|
||||
/*****************************
|
||||
** Address-space interface **
|
||||
*****************************/
|
||||
|
||||
void flush(addr_t, size_t, Core_local_addr) override;
|
||||
};
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_PD_H_ */
|
||||
|
@ -26,164 +26,167 @@
|
||||
namespace Genode {
|
||||
|
||||
class Platform_pd;
|
||||
class Platform_thread
|
||||
{
|
||||
private:
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Platform_thread(Platform_thread const &);
|
||||
Platform_thread &operator = (Platform_thread const &);
|
||||
|
||||
int _thread_id = THREAD_INVALID; /* plain thread number */
|
||||
|
||||
Okl4::L4_ThreadId_t _l4_thread_id; /* L4 thread ID */
|
||||
|
||||
char _name[32]; /* thread name that will be
|
||||
registered at the kernel
|
||||
debugger */
|
||||
Platform_pd *_platform_pd; /* protection domain thread
|
||||
is bound to */
|
||||
unsigned _priority; /* thread priority */
|
||||
Pager_object *_pager;
|
||||
|
||||
public:
|
||||
|
||||
enum { THREAD_INVALID = -1 }; /* invalid thread number */
|
||||
enum { DEFAULT_PRIORITY = 128 };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform_thread(size_t, const char *name,
|
||||
unsigned priority,
|
||||
Affinity::Location,
|
||||
addr_t utcb);
|
||||
|
||||
/**
|
||||
* Constructor used for core-internal threads
|
||||
*/
|
||||
Platform_thread(char const *name)
|
||||
: Platform_thread(0, name, 0, Affinity::Location(), 0) { }
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Platform_thread();
|
||||
|
||||
/**
|
||||
* Start thread
|
||||
*
|
||||
* \param ip instruction pointer to start at
|
||||
* \param sp stack pointer to use
|
||||
* \param cpu_no target cpu
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread could not be started
|
||||
*/
|
||||
int start(void *ip, void *sp, unsigned int cpu_no = 0);
|
||||
|
||||
/**
|
||||
* Pause this thread
|
||||
*/
|
||||
void pause();
|
||||
|
||||
/**
|
||||
* Enable/disable single stepping
|
||||
*/
|
||||
void single_step(bool) { }
|
||||
|
||||
/**
|
||||
* Resume this thread
|
||||
*/
|
||||
void resume();
|
||||
|
||||
/**
|
||||
* This thread is about to be bound
|
||||
*
|
||||
* \param thread_id local thread ID
|
||||
* \param l4_thread_id final L4 thread ID
|
||||
* \param pd platform pd, thread is bound to
|
||||
*/
|
||||
void bind(int thread_id, Okl4::L4_ThreadId_t l4_thread_id,
|
||||
Platform_pd &pd);
|
||||
|
||||
/**
|
||||
* Unbind this thread
|
||||
*/
|
||||
void unbind();
|
||||
|
||||
/**
|
||||
* Override thread state with 's'
|
||||
*
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
void state(Thread_state s);
|
||||
|
||||
/**
|
||||
* Read thread state
|
||||
*/
|
||||
Thread_state state();
|
||||
|
||||
/************************
|
||||
** Accessor functions **
|
||||
************************/
|
||||
|
||||
/**
|
||||
* Return/set pager
|
||||
*/
|
||||
Pager_object &pager() const
|
||||
{
|
||||
if (_pager)
|
||||
return *_pager;
|
||||
|
||||
ASSERT_NEVER_CALLED;
|
||||
}
|
||||
|
||||
void pager(Pager_object &pager) { _pager = &pager; }
|
||||
|
||||
/**
|
||||
* Get the 'Platform_pd' object this thread belongs to
|
||||
*/
|
||||
Platform_pd* pd() { return _platform_pd; }
|
||||
|
||||
/**
|
||||
* Return identification of thread when faulting
|
||||
*/
|
||||
unsigned long pager_object_badge() const;
|
||||
|
||||
/**
|
||||
* Set the executing CPU for this thread
|
||||
*/
|
||||
void affinity(Affinity::Location) { }
|
||||
|
||||
/**
|
||||
* Request the affinity of this thread
|
||||
*/
|
||||
Affinity::Location affinity() const { return Affinity::Location(); }
|
||||
|
||||
/**
|
||||
* Set CPU quota of the thread
|
||||
*/
|
||||
void quota(size_t) { /* not supported */ }
|
||||
|
||||
/**
|
||||
* Return execution time consumed by the thread
|
||||
*/
|
||||
Trace::Execution_time execution_time() const { return { 0, 0 }; }
|
||||
|
||||
|
||||
/*****************************
|
||||
** OKL4-specific Accessors **
|
||||
*****************************/
|
||||
|
||||
int thread_id() const { return _thread_id; }
|
||||
Okl4::L4_ThreadId_t native_thread_id() const { return _l4_thread_id; }
|
||||
const char *name() const { return _name; }
|
||||
|
||||
void set_l4_thread_id(Okl4::L4_ThreadId_t id) { _l4_thread_id = id; }
|
||||
};
|
||||
class Platform_thread;
|
||||
}
|
||||
|
||||
|
||||
class Genode::Platform_thread
|
||||
{
|
||||
private:
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Platform_thread(Platform_thread const &);
|
||||
Platform_thread &operator = (Platform_thread const &);
|
||||
|
||||
int _thread_id = THREAD_INVALID; /* plain thread number */
|
||||
|
||||
Okl4::L4_ThreadId_t _l4_thread_id; /* L4 thread ID */
|
||||
|
||||
char _name[32]; /* thread name that will be
|
||||
registered at the kernel
|
||||
debugger */
|
||||
Platform_pd *_platform_pd; /* protection domain thread
|
||||
is bound to */
|
||||
unsigned _priority; /* thread priority */
|
||||
Pager_object *_pager;
|
||||
|
||||
public:
|
||||
|
||||
enum { THREAD_INVALID = -1 }; /* invalid thread number */
|
||||
enum { DEFAULT_PRIORITY = 128 };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform_thread(size_t, const char *name,
|
||||
unsigned priority,
|
||||
Affinity::Location,
|
||||
addr_t utcb);
|
||||
|
||||
/**
|
||||
* Constructor used for core-internal threads
|
||||
*/
|
||||
Platform_thread(char const *name)
|
||||
: Platform_thread(0, name, 0, Affinity::Location(), 0) { }
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Platform_thread();
|
||||
|
||||
/**
|
||||
* Start thread
|
||||
*
|
||||
* \param ip instruction pointer to start at
|
||||
* \param sp stack pointer to use
|
||||
* \param cpu_no target cpu
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread could not be started
|
||||
*/
|
||||
int start(void *ip, void *sp, unsigned int cpu_no = 0);
|
||||
|
||||
/**
|
||||
* Pause this thread
|
||||
*/
|
||||
void pause();
|
||||
|
||||
/**
|
||||
* Enable/disable single stepping
|
||||
*/
|
||||
void single_step(bool) { }
|
||||
|
||||
/**
|
||||
* Resume this thread
|
||||
*/
|
||||
void resume();
|
||||
|
||||
/**
|
||||
* This thread is about to be bound
|
||||
*
|
||||
* \param thread_id local thread ID
|
||||
* \param l4_thread_id final L4 thread ID
|
||||
* \param pd platform pd, thread is bound to
|
||||
*/
|
||||
void bind(int thread_id, Okl4::L4_ThreadId_t l4_thread_id,
|
||||
Platform_pd &pd);
|
||||
|
||||
/**
|
||||
* Unbind this thread
|
||||
*/
|
||||
void unbind();
|
||||
|
||||
/**
|
||||
* Override thread state with 's'
|
||||
*
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
void state(Thread_state s);
|
||||
|
||||
/**
|
||||
* Read thread state
|
||||
*/
|
||||
Thread_state state();
|
||||
|
||||
/************************
|
||||
** Accessor functions **
|
||||
************************/
|
||||
|
||||
/**
|
||||
* Return/set pager
|
||||
*/
|
||||
Pager_object &pager() const
|
||||
{
|
||||
if (_pager)
|
||||
return *_pager;
|
||||
|
||||
ASSERT_NEVER_CALLED;
|
||||
}
|
||||
|
||||
void pager(Pager_object &pager) { _pager = &pager; }
|
||||
|
||||
/**
|
||||
* Get the 'Platform_pd' object this thread belongs to
|
||||
*/
|
||||
Platform_pd* pd() { return _platform_pd; }
|
||||
|
||||
/**
|
||||
* Return identification of thread when faulting
|
||||
*/
|
||||
unsigned long pager_object_badge() const;
|
||||
|
||||
/**
|
||||
* Set the executing CPU for this thread
|
||||
*/
|
||||
void affinity(Affinity::Location) { }
|
||||
|
||||
/**
|
||||
* Request the affinity of this thread
|
||||
*/
|
||||
Affinity::Location affinity() const { return Affinity::Location(); }
|
||||
|
||||
/**
|
||||
* Set CPU quota of the thread
|
||||
*/
|
||||
void quota(size_t) { /* not supported */ }
|
||||
|
||||
/**
|
||||
* Return execution time consumed by the thread
|
||||
*/
|
||||
Trace::Execution_time execution_time() const { return { 0, 0 }; }
|
||||
|
||||
|
||||
/*****************************
|
||||
** OKL4-specific Accessors **
|
||||
*****************************/
|
||||
|
||||
int thread_id() const { return _thread_id; }
|
||||
Okl4::L4_ThreadId_t native_thread_id() const { return _l4_thread_id; }
|
||||
const char *name() const { return _name; }
|
||||
|
||||
void set_l4_thread_id(Okl4::L4_ThreadId_t id) { _l4_thread_id = id; }
|
||||
};
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_THREAD_H_ */
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
namespace Genode { class Rpc_cap_factory; }
|
||||
|
||||
|
||||
class Genode::Rpc_cap_factory
|
||||
{
|
||||
private:
|
||||
|
@ -165,7 +165,7 @@ void Irq_session_component::sigh(Genode::Signal_context_capability cap)
|
||||
}
|
||||
|
||||
|
||||
Genode::Irq_session::Info Irq_session_component::info()
|
||||
Irq_session::Info Irq_session_component::info()
|
||||
{
|
||||
/* no MSI support */
|
||||
return { .type = Info::Type::INVALID, .address = 0, .value = 0 };
|
||||
|
@ -53,10 +53,10 @@ static inline void print_page_fault(L4_Word_t type, L4_Word_t addr, L4_Word_t ip
|
||||
* identity. By convention, each thread stores its global ID in a
|
||||
* defined entry of its UTCB.
|
||||
*/
|
||||
static inline Okl4::L4_ThreadId_t thread_get_my_global_id()
|
||||
static inline L4_ThreadId_t thread_get_my_global_id()
|
||||
{
|
||||
Okl4::L4_ThreadId_t myself;
|
||||
myself.raw = Okl4::__L4_TCR_ThreadWord(UTCB_TCR_THREAD_WORD_MYSELF);
|
||||
L4_ThreadId_t myself;
|
||||
myself.raw = __L4_TCR_ThreadWord(UTCB_TCR_THREAD_WORD_MYSELF);
|
||||
return myself;
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,13 @@
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Ram_dataspace_factory::_export_ram_ds(Dataspace_component &) { }
|
||||
|
||||
|
||||
void Ram_dataspace_factory::_revoke_ram_ds(Dataspace_component &) { }
|
||||
|
||||
|
||||
void Ram_dataspace_factory::_clear_ds (Dataspace_component &ds)
|
||||
{
|
||||
size_t page_rounded_size = (ds.size() + get_page_size() - 1) & get_page_mask();
|
||||
|
@ -46,6 +46,8 @@ namespace Okl4
|
||||
}
|
||||
}
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/*****************************
|
||||
** Startup library support **
|
||||
@ -70,15 +72,17 @@ void prepare_reinit_main_thread() { prepare_init_main_thread(); }
|
||||
** Thread **
|
||||
************/
|
||||
|
||||
void Genode::Thread::_thread_bootstrap()
|
||||
void Thread::_thread_bootstrap()
|
||||
{
|
||||
native_thread().l4id.raw = Okl4::copy_uregister_to_utcb();
|
||||
}
|
||||
|
||||
|
||||
void Genode::Thread::_init_platform_thread(size_t, Type type)
|
||||
void Thread::_init_platform_thread(size_t, Type type)
|
||||
{
|
||||
if (type == NORMAL) { return; }
|
||||
if (type == NORMAL)
|
||||
return;
|
||||
|
||||
native_thread().l4id.raw = main_thread_tid.raw;
|
||||
_thread_cap = main_thread_cap();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user