base-foc: coding style

- Cosmetic adjustments according to
  https://genode.org/documentation/developer-resources/coding_style

- Replace manual inclusion of kernel headers by one new compound
  header foc/syscall.h

- Rename namespace Fiasco to Foc
This commit is contained in:
Norman Feske 2020-11-27 18:10:19 +01:00
parent 0209a2465d
commit 70ff3d9c90
60 changed files with 1508 additions and 1462 deletions

View File

@ -25,17 +25,17 @@ namespace Genode { namespace Capability_space {
* Allocate kernel capability selector without associating it with a
* Genode capability
*/
Fiasco::l4_cap_idx_t alloc_kcap();
Foc::l4_cap_idx_t alloc_kcap();
/**
* Release kernel capability selector
*/
void free_kcap(Fiasco::l4_cap_idx_t);
void free_kcap(Foc::l4_cap_idx_t);
/**
* Request kernel capability selector associated with Genode capability
*/
Fiasco::l4_cap_idx_t kcap(Native_capability);
Foc::l4_cap_idx_t kcap(Native_capability);
} }

View File

@ -14,18 +14,16 @@
#ifndef _INCLUDE__FOC__NATIVE_CAPABILITY_H_
#define _INCLUDE__FOC__NATIVE_CAPABILITY_H_
namespace Fiasco {
#include <l4/sys/consts.h>
#include <l4/sys/types.h>
#include <l4/sys/utcb.h>
#include <l4/sys/task.h>
#include <foc/syscall.h>
namespace Foc {
/*********************************************
** Capability selectors controlled by core **
*********************************************/
/* use the same task cap selector like L4Re for compatibility in L4Linux */
static constexpr l4_cap_idx_t TASK_CAP = L4_BASE_TASK_CAP;
static constexpr l4_cap_idx_t TASK_CAP = L4_BASE_TASK_CAP;
static constexpr l4_cap_idx_t DEBUG_CAP = L4_BASE_DEBUGGER_CAP;

View File

@ -21,23 +21,20 @@
/* Genode includes */
#include <base/stdint.h>
#include <foc/receive_window.h>
/* Fiasco.OC includes */
namespace Fiasco {
#include <l4/sys/types.h>
}
#include <foc/syscall.h>
namespace Genode { struct Native_thread; }
struct Genode::Native_thread
{
Fiasco::l4_cap_idx_t kcap = 0;
Foc::l4_cap_idx_t kcap = 0;
/* receive window for capability selectors received at the server side */
Receive_window rcv_window { };
Native_thread() { }
explicit Native_thread(Fiasco::l4_cap_idx_t kcap) : kcap(kcap) { }
explicit Native_thread(Foc::l4_cap_idx_t kcap) : kcap(kcap) { }
};
#endif /* _INCLUDE__FOC__NATIVE_THREAD_H_ */

View File

@ -0,0 +1,36 @@
/*
* \brief Collection of Fiasco.OC kernel bindings
* \author Norman Feske
* \date 2020-11-27
*/
/*
* Copyright (C) 2020 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__FOC__SYSCALL_H_
#define _INCLUDE__FOC__SYSCALL_H_
namespace Foc {
#include <l4/sys/types.h>
#include <l4/sys/kip>
#include <l4/sys/kdebug.h>
#include <l4/sys/cache.h>
#include <l4/sys/consts.h>
#include <l4/sys/utcb.h>
#include <l4/sys/task.h>
#include <l4/sys/ipc.h>
#include <l4/sys/thread.h>
#include <l4/sys/factory.h>
#include <l4/sys/irq.h>
#include <l4/sys/debugger.h>
#include <l4/sys/icu.h>
#include <l4/sys/ktrace.h>
#include <l4/sys/scheduler.h>
#include <l4/sigma0/sigma0.h>
}
#endif /* _INCLUDE__FOC__SYSCALL_H_ */

View File

@ -18,25 +18,21 @@
#include <base/capability.h>
#include <base/thread_state.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/types.h>
}
#include <foc/syscall.h>
namespace Genode { struct Foc_thread_state; }
struct Genode::Foc_thread_state : Thread_state
{
Fiasco::l4_cap_idx_t kcap; /* thread's gate cap in its pd */
int id; /* id of gate capability */
addr_t utcb; /* thread's utcb in its pd */
Foc::l4_cap_idx_t kcap; /* thread's gate cap in its PD */
int id; /* ID of gate capability */
addr_t utcb; /* thread's UTCB in its PD */
/**
* Constructor
*/
Foc_thread_state() : kcap(Fiasco::L4_INVALID_CAP), id(0), utcb(0) { }
Foc_thread_state() : kcap(Foc::L4_INVALID_CAP), id(0), utcb(0) { }
};
#endif /* _INCLUDE__FOC__THREAD_STATE_H_ */

View File

@ -14,7 +14,13 @@
/* core includes */
#include <core_log.h>
namespace Fiasco {
#include <l4/sys/kdebug.h>
/* Fiasco.OC includes */
#include <foc/syscall.h>
using namespace Genode;
void Core_log::out(char const c)
{
Foc::outchar(c);
}
void Genode::Core_log::out(char const c) { Fiasco::outchar(c); }

View File

@ -20,33 +20,32 @@
#include <base/mutex.h>
#include <synced_range_allocator.h>
namespace Genode {
class Cap_id_allocator
{
private:
enum {
CAP_ID_RANGE = ~0UL,
CAP_ID_MASK = ~3UL,
CAP_ID_NUM_MAX = CAP_ID_MASK >> 2,
CAP_ID_OFFSET = 1 << 2
};
Synced_range_allocator<Allocator_avl> _id_alloc;
Mutex _mutex { };
public:
class Out_of_ids : Exception {};
namespace Genode { class Cap_id_allocator; }
Cap_id_allocator(Allocator &);
class Genode::Cap_id_allocator
{
private:
unsigned long alloc();
void free(unsigned long id);
};
}
enum {
CAP_ID_RANGE = ~0UL,
CAP_ID_MASK = ~3UL,
CAP_ID_NUM_MAX = CAP_ID_MASK >> 2,
CAP_ID_OFFSET = 1 << 2
};
Synced_range_allocator<Allocator_avl> _id_alloc;
Mutex _mutex { };
public:
class Out_of_ids : Exception {};
Cap_id_allocator(Allocator &);
unsigned long alloc();
void free(unsigned long id);
};
#endif /* _CORE__INCLUDE__CAP_ID_ALLOC_H_ */

View File

@ -45,7 +45,9 @@ class Genode::Core_cap_index : public Native_capability::Data
Core_cap_index(Pd_session_component *session = 0,
Platform_thread *pt = 0,
Native_thread gate = Native_thread() )
: _session(session), _pt(pt), _gate(gate) {}
:
_session(session), _pt(pt), _gate(gate)
{ }
Pd_session_component const *session() const { return _session; }
Platform_thread const *pt() const { return _pt; }

View File

@ -1,5 +1,5 @@
/*
* \brief Fiasco.OC specific capability mapping.
* \brief Fiasco.OC specific capability mapping
* \author Stefan Kalkowski
* \date 2012-02-22
*/
@ -18,43 +18,44 @@
#include <cap_index.h>
#include <util/noncopyable.h>
namespace Genode {
namespace Genode { class Cap_mapping; }
/**
* A Cap_mapping embodies a capability of core, and its mapped
* copy in another protection domain.
*/
class Cap_mapping : Noncopyable
{
private:
/**
* Helper function for construction purposes.
*
* Allocates a new capability id and Core_cap_index and inserts
* it in the Cap_map.
*
* \return pointer to newly constructed Core_cap_index object
*/
inline Core_cap_index *_get_cap();
/**
* A Cap_mapping embodies a capability of core, and its mapped
* copy in another protection domain.
*/
class Genode::Cap_mapping : Noncopyable
{
private:
public:
/**
* Helper function for construction purposes.
*
* Allocates a new capability id and Core_cap_index and inserts
* it in the Cap_map.
*
* \return pointer to newly constructed Core_cap_index object
*/
inline Core_cap_index *_get_cap();
Native_capability local; /* reference to cap that is mapped */
Fiasco::l4_cap_idx_t remote; /* index in cap-space of the other pd */
public:
Cap_mapping(bool alloc=false,
Fiasco::l4_cap_idx_t r = Fiasco::L4_INVALID_CAP);
Cap_mapping(Native_capability cap,
Fiasco::l4_cap_idx_t r = Fiasco::L4_INVALID_CAP);
Native_capability local; /* reference to cap that is mapped */
Foc::l4_cap_idx_t remote; /* index in cap-space of the other pd */
/**
* Map the cap in local to corresponding task.
*
* \param task capability of task to map to
*/
void map(Fiasco::l4_cap_idx_t task);
};
}
Cap_mapping(bool alloc=false,
Foc::l4_cap_idx_t r = Foc::L4_INVALID_CAP);
Cap_mapping(Native_capability cap,
Foc::l4_cap_idx_t r = Foc::L4_INVALID_CAP);
/**
* Map the cap in local to corresponding task.
*
* \param task capability of task to map to
*/
void map(Foc::l4_cap_idx_t task);
};
#endif /* _CORE__INCLUDE__CAP_MAPPING_H_ */

View File

@ -28,22 +28,22 @@
/* base-internal includes */
#include <base/internal/native_thread.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/types.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
namespace Genode {
class Mapping;
class Ipc_pager;
}
class Genode::Mapping
{
private:
addr_t _dst_addr;
Fiasco::l4_fpage_t _fpage { };
Foc::l4_fpage_t _fpage { };
Cache_attribute _cacheability;
bool _iomem;
@ -55,26 +55,27 @@ class Genode::Mapping
Mapping(addr_t dst_addr, addr_t src_addr,
Cache_attribute c, bool io_mem,
unsigned log2size, bool write, bool executable)
: _dst_addr(dst_addr), _cacheability(c), _iomem(io_mem)
:
_dst_addr(dst_addr), _cacheability(c), _iomem(io_mem)
{
typedef Fiasco::L4_fpage_rights Rights;
Rights rights = (write && executable) ? Fiasco::L4_FPAGE_RWX :
(write && !executable) ? Fiasco::L4_FPAGE_RW :
(!write && !executable) ? Fiasco::L4_FPAGE_RO :
Fiasco::L4_FPAGE_RX;
typedef Foc::L4_fpage_rights Rights;
Rights rights = ( write && executable) ? Foc::L4_FPAGE_RWX :
( write && !executable) ? Foc::L4_FPAGE_RW :
(!write && !executable) ? Foc::L4_FPAGE_RO :
Foc::L4_FPAGE_RX;
_fpage = Fiasco::l4_fpage(src_addr, log2size, rights);
_fpage = Foc::l4_fpage(src_addr, log2size, rights);
}
/**
* Construct invalid flexpage
*/
Mapping() : _dst_addr(0), _fpage(Fiasco::l4_fpage_invalid()),
Mapping() : _dst_addr(0), _fpage(Foc::l4_fpage_invalid()),
_cacheability(UNCACHED), _iomem(false) { }
Fiasco::l4_umword_t dst_addr() const { return _dst_addr; }
Foc::l4_umword_t dst_addr() const { return _dst_addr; }
bool grant() const { return false; }
Fiasco::l4_fpage_t fpage() const { return _fpage; }
Foc::l4_fpage_t fpage() const { return _fpage; }
Cache_attribute cacheability() const { return _cacheability; }
bool iomem() const { return _iomem; }
/**
@ -101,8 +102,8 @@ class Genode::Ipc_pager : public Native_capability
addr_t _pf_ip { 0 }; /* ip of faulter */
Mapping _reply_mapping { }; /* page-fault answer */
unsigned long _badge; /* badge of faulting thread */
Fiasco::l4_msgtag_t _tag { }; /* receive message tag */
Fiasco::l4_exc_regs_t _regs { }; /* exception registers */
Foc::l4_msgtag_t _tag { }; /* receive message tag */
Foc::l4_exc_regs_t _regs { }; /* exception registers */
Msg_type _type { PAGEFAULT };
void _parse_msg_type(void);

View File

@ -38,12 +38,12 @@ class Genode::Irq_object
Irq_session::Polarity _polarity; /* interrupt polarity */
unsigned _irq;
Genode::addr_t _msi_addr;
Genode::addr_t _msi_data;
addr_t _msi_addr;
addr_t _msi_data;
Signal_context_capability _sig_cap { };
Fiasco::l4_cap_idx_t _capability() const { return _cap->kcap(); }
Foc::l4_cap_idx_t _capability() const { return _cap->kcap(); }
public:

View File

@ -19,13 +19,8 @@
#include <platform.h>
#include <util.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/ipc.h>
#include <l4/sigma0/sigma0.h>
#include <l4/sys/task.h>
#include <l4/sys/cache.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
namespace Genode {
@ -47,7 +42,7 @@ namespace Genode {
size_t page_size_log2 = get_page_size_log2();
for (unsigned i = 0; i < num_pages; i++, offset += page_size) {
using namespace Fiasco;
using namespace Foc;
l4_fpage_t snd_fpage = l4_fpage(from_addr + offset,
page_size_log2, L4_FPAGE_RW);
@ -84,7 +79,7 @@ namespace Genode {
static inline bool map_local_io(addr_t from_addr, addr_t to_addr,
size_t num_pages)
{
using namespace Fiasco;
using namespace Foc;
size_t size = num_pages << get_page_size_log2();
@ -129,7 +124,7 @@ namespace Genode {
static inline void unmap_local(addr_t const local_base, size_t const num_pages)
{
using namespace Fiasco;
using namespace Foc;
size_t const size = num_pages << get_page_size_log2();
addr_t addr = local_base;

View File

@ -19,6 +19,7 @@
namespace Genode { struct Pager_object_exception_state; }
struct Genode::Pager_object_exception_state
{
Mutex mutex { };

View File

@ -17,6 +17,7 @@
#define _CORE__INCLUDE__PLATFORM_H_
/* Genode includes */
#include <util/xml_generator.h>
#include <base/synced_allocator.h>
#include <base/allocator_avl.h>
@ -28,163 +29,160 @@
#include <platform_pd.h>
#include <assertion.h>
namespace Fiasco {
struct l4_kernel_info_t;
}
namespace Foc { struct l4_kernel_info_t; }
namespace Genode {
class Xml_generator;
namespace Genode { class Platform; }
class Platform : public Platform_generic
{
private:
/*
* Noncopyable
*/
Platform(Platform const &);
Platform &operator = (Platform const &);
class Genode::Platform : public Platform_generic
{
private:
/**
* Pager object representing the pager of core namely sigma0
*/
struct Sigma0 : public Pager_object
{
/**
* Constructor
*/
Sigma0(Cap_index*);
int pager(Ipc_pager &) override { /* never called */ return -1; }
};
/*
* Shortcut for the type of allocator instances for physical resources
*/
typedef Synced_range_allocator<Allocator_avl> Phys_allocator;
Platform_pd *_core_pd = nullptr; /* core protection domain object */
Phys_allocator _ram_alloc; /* RAM allocator */
Phys_allocator _io_mem_alloc; /* MMIO allocator */
Phys_allocator _io_port_alloc; /* I/O port allocator */
Phys_allocator _irq_alloc; /* IRQ allocator */
Phys_allocator _region_alloc; /* virtual memory allocator for core */
Cap_id_allocator _cap_id_alloc; /* capability id allocator */
Rom_fs _rom_fs { }; /* ROM file system */
Rom_module _kip_rom; /* ROM module for Fiasco KIP */
Sigma0 _sigma0;
addr_t _vm_start = 0; /* begin of virtual memory */
size_t _vm_size = 0; /* size of virtual memory */
/**
* Setup base resources
*
* - Map and provide KIP as ROM module
* - Initializes region allocator
*/
void _setup_basics();
/**
* Setup RAM, IO_MEM, and region allocators
*/
void _setup_mem_alloc();
/**
* Setup I/O port space allocator
*/
void _setup_io_port_alloc();
/**
* Setup content of platform_info ROM
*/
void _setup_platform_info(Xml_generator &,
Fiasco::l4_kernel_info_t &);
/**
* Setup IRQ allocator
*/
void _setup_irq_alloc();
/**
* Parse multi-boot information and update ROM database
*/
void _init_rom_modules();
/**
* Setup pager for core-internal threads
*/
void _setup_core_pager();
addr_t _rom_module_phys(addr_t virt) { return virt; }
public:
enum { VCPU_VIRT_EXT_START = 0x1000, VCPU_VIRT_EXT_END = 0x10000 };
/**
* Core pager thread that handles core-internal page-faults
*/
struct Core_pager : public Platform_thread, public Pager_object
{
/**
* Constructor
*/
Core_pager(Platform_pd &core_pd, Sigma0 &);
int pager(Ipc_pager &) override { /* never called */ return -1; }
};
/**
* Return singleton instance of core pager object
*/
Core_pager &core_pager();
/**
* Set interrupt trigger/polarity (e.g., level or edge, high or low)
*/
static void setup_irq_mode(unsigned irq_number, unsigned trigger,
unsigned polarity);
/*
* Noncopyable
*/
Platform(Platform const &);
Platform &operator = (Platform const &);
/**
* Pager object representing the pager of core namely sigma0
*/
struct Sigma0 : public Pager_object
{
/**
* Constructor
*/
Platform();
Sigma0(Cap_index*);
int pager(Ipc_pager &) override { /* never called */ return -1; }
};
/*
* Shortcut for the type of allocator instances for physical resources
*/
typedef Synced_range_allocator<Allocator_avl> Phys_allocator;
Platform_pd *_core_pd = nullptr; /* core protection domain object */
Phys_allocator _ram_alloc; /* RAM allocator */
Phys_allocator _io_mem_alloc; /* MMIO allocator */
Phys_allocator _io_port_alloc; /* I/O port allocator */
Phys_allocator _irq_alloc; /* IRQ allocator */
Phys_allocator _region_alloc; /* virtual memory allocator for core */
Cap_id_allocator _cap_id_alloc; /* capability id allocator */
Rom_fs _rom_fs { }; /* ROM file system */
Rom_module _kip_rom; /* ROM module for Fiasco.OC KIP */
Sigma0 _sigma0;
addr_t _vm_start = 0; /* begin of virtual memory */
size_t _vm_size = 0; /* size of virtual memory */
/**
* Setup base resources
*
* - Map and provide KIP as ROM module
* - Initializes region allocator
*/
void _setup_basics();
/**
* Setup RAM, IO_MEM, and region allocators
*/
void _setup_mem_alloc();
/**
* Setup I/O port space allocator
*/
void _setup_io_port_alloc();
/**
* Setup content of platform_info ROM
*/
void _setup_platform_info(Xml_generator &,
Foc::l4_kernel_info_t &);
/**
* Setup IRQ allocator
*/
void _setup_irq_alloc();
/**
* Parse multi-boot information and update ROM database
*/
void _init_rom_modules();
/**
* Setup pager for core-internal threads
*/
void _setup_core_pager();
addr_t _rom_module_phys(addr_t virt) { return virt; }
public:
enum { VCPU_VIRT_EXT_START = 0x1000, VCPU_VIRT_EXT_END = 0x10000 };
/**
* Core pager thread that handles core-internal page-faults
*/
struct Core_pager : Platform_thread, Pager_object
{
/**
* Accessor for core pd object
* Constructor
*/
Platform_pd &core_pd()
{
if (_core_pd)
return *_core_pd;
Core_pager(Platform_pd &core_pd, Sigma0 &);
ASSERT_NEVER_CALLED;
}
int pager(Ipc_pager &) override { /* never called */ return -1; }
};
/**
* Return singleton instance of core pager object
*/
Core_pager &core_pager();
/**
* Set interrupt trigger/polarity (e.g., level or edge, high or low)
*/
static void setup_irq_mode(unsigned irq_number, unsigned trigger,
unsigned polarity);
/**
* Constructor
*/
Platform();
/**
* Accessor for core pd object
*/
Platform_pd &core_pd()
{
if (_core_pd)
return *_core_pd;
ASSERT_NEVER_CALLED;
}
/********************************
** Generic platform interface **
********************************/
/********************************
** Generic platform interface **
********************************/
Range_allocator &core_mem_alloc() override { return _ram_alloc; }
Range_allocator &ram_alloc() override { return _ram_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 &region_alloc() override { return _region_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; }
Affinity::Space affinity_space() const override;
Range_allocator &core_mem_alloc() override { return _ram_alloc; }
Range_allocator &ram_alloc() override { return _ram_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 &region_alloc() override { return _region_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; }
Affinity::Space affinity_space() const override;
size_t max_caps() const override { return cap_idx_alloc().max_caps(); }
size_t max_caps() const override { return cap_idx_alloc().max_caps(); }
Cap_id_allocator &cap_id_alloc() { return _cap_id_alloc; }
Cap_id_allocator &cap_id_alloc() { return _cap_id_alloc; }
void wait_for_exit() override;
};
}
void wait_for_exit() override;
};
#endif /* _CORE__INCLUDE__PLATFORM_H_ */

View File

@ -34,89 +34,88 @@
#include <base/internal/non_core_stack_area_addr.h>
/* Fiasco.OC includes */
namespace Fiasco {
#include <l4/sys/consts.h>
}
#include <foc/syscall.h>
namespace Genode {
class Platform_thread;
class Platform_pd : public Address_space
{
private:
/*
* Noncopyable
*/
Platform_pd(Platform_pd const &);
Platform_pd &operator = (Platform_pd const &);
enum {
UTCB_AREA_SIZE = (Fiasco::THREAD_MAX * Fiasco::L4_UTCB_OFFSET),
};
addr_t utcb_area_start()
{
return NON_CORE_STACK_AREA_ADDR +
Fiasco::THREAD_MAX*stack_virtual_size();
}
Cap_mapping _task;
Cap_mapping _parent { };
Cap_mapping _debug { };
Platform_thread *_threads[Fiasco::THREAD_MAX] { };
public:
class Threads_exhausted : Exception {};
/**
* Constructor for core
*/
Platform_pd(Core_cap_index &);
/**
* Constructor for all tasks except core.
*/
Platform_pd(Allocator &, char const *label);
/**
* Destructor
*/
~Platform_pd();
/**
* Bind thread to protection domain
*/
bool bind_thread(Platform_thread &);
/**
* Unbind thread from protection domain
*
* Free the thread's slot and update thread object.
*/
void unbind_thread(Platform_thread &);
/**
* Assign parent interface to protection domain
*/
void assign_parent(Native_capability parent);
/*******************************
** Fiasco-specific Accessors **
*******************************/
Native_capability native_task() { return _task.local; }
/*****************************
** Address-space interface **
*****************************/
void flush(addr_t, size_t, Core_local_addr) override;
};
class Platform_pd;
}
class Genode::Platform_pd : public Address_space
{
private:
/*
* Noncopyable
*/
Platform_pd(Platform_pd const &);
Platform_pd &operator = (Platform_pd const &);
enum { UTCB_AREA_SIZE = (Foc::THREAD_MAX * Foc::L4_UTCB_OFFSET), };
addr_t utcb_area_start()
{
return NON_CORE_STACK_AREA_ADDR +
Foc::THREAD_MAX*stack_virtual_size();
}
Cap_mapping _task;
Cap_mapping _parent { };
Cap_mapping _debug { };
Platform_thread *_threads[Foc::THREAD_MAX] { };
public:
class Threads_exhausted : Exception {};
/**
* Constructor for core
*/
Platform_pd(Core_cap_index &);
/**
* Constructor for all tasks except core.
*/
Platform_pd(Allocator &, char const *label);
/**
* Destructor
*/
~Platform_pd();
/**
* Bind thread to protection domain
*/
bool bind_thread(Platform_thread &);
/**
* Unbind thread from protection domain
*
* Free the thread's slot and update thread object.
*/
void unbind_thread(Platform_thread &);
/**
* Assign parent interface to protection domain
*/
void assign_parent(Native_capability parent);
/**********************************
** Fiasco.OC-specific Accessors **
**********************************/
Native_capability native_task() { return _task.local; }
/*****************************
** Address-space interface **
*****************************/
void flush(addr_t, size_t, Core_local_addr) override;
};
#endif /* _CORE__INCLUDE__PLATFORM_PD_H_ */

View File

@ -1,5 +1,5 @@
/*
* \brief Fiasco thread facility
* \brief Fiasco.OC thread facility
* \author Christian Helmuth
* \author Stefan Kalkowski
* \date 2006-04-11
@ -29,180 +29,184 @@
namespace Genode {
class Platform_pd;
class Platform_thread : Interface
{
private:
/*
* Noncopyable
*/
Platform_thread(Platform_thread const &);
Platform_thread &operator = (Platform_thread const &);
enum State { DEAD, RUNNING };
typedef String<32> Name;
friend class Platform_pd;
Name const _name; /* name at kernel debugger */
State _state;
bool _core_thread;
Cap_mapping _thread;
Cap_mapping _gate { };
Cap_mapping _pager { };
Cap_mapping _irq;
addr_t _utcb;
Platform_pd *_platform_pd; /* protection domain thread
is bound to */
Pager_object *_pager_obj;
unsigned _prio;
Affinity::Location _location { };
void _create_thread(void);
void _finalize_construction();
bool _in_syscall(Fiasco::l4_umword_t flags);
public:
enum { DEFAULT_PRIORITY = 128 };
/**
* Constructor for non-core threads
*/
Platform_thread(size_t, const char *name, unsigned priority,
Affinity::Location, addr_t);
/**
* Constructor for core main-thread
*/
Platform_thread(Core_cap_index& thread,
Core_cap_index& irq, const char *name);
/**
* Constructor for core threads
*/
Platform_thread(const char *name);
/**
* Destructor
*/
~Platform_thread();
/**
* Start thread
*
* \param ip instruction pointer to start at
* \param sp stack pointer to use
*
* \retval 0 successful
* \retval -1 thread could not be started
*/
int start(void *ip, void *sp);
/**
* 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 pd platform pd, thread is bound to
*/
void bind(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
*
* \throw Cpu_session::State_access_failed
*/
Foc_thread_state state();
/**
* Set the executing CPU for this thread
*/
void affinity(Affinity::Location location);
/**
* Get the executing CPU for this thread
*/
Affinity::Location affinity() const;
/**
* Make thread to vCPU
*/
Fiasco::l4_cap_idx_t setup_vcpu(unsigned, Cap_mapping const &,
Cap_mapping &);
/************************
** Accessor functions **
************************/
/**
* Return/set pager
*/
Pager_object &pager() const
{
if (_pager_obj)
return *_pager_obj;
ASSERT_NEVER_CALLED;
}
void pager(Pager_object &pager);
/**
* Return identification of thread when faulting
*/
unsigned long pager_object_badge() {
return (unsigned long) _thread.local.data()->kcap(); }
/**
* Set CPU quota of the thread to 'quota'
*/
void quota(size_t const) { /* not supported*/ }
/**
* Return execution time consumed by the thread
*/
Trace::Execution_time execution_time() const;
/*******************************
** Fiasco-specific Accessors **
*******************************/
Cap_mapping const & thread() const { return _thread; }
Cap_mapping & gate() { return _gate; }
Name name() const { return _name; }
bool core_thread() const { return _core_thread; }
addr_t utcb() const { return _utcb; }
unsigned prio() const { return _prio; }
};
class Platform_thread;
}
class Genode::Platform_thread : Interface
{
private:
/*
* Noncopyable
*/
Platform_thread(Platform_thread const &);
Platform_thread &operator = (Platform_thread const &);
enum State { DEAD, RUNNING };
typedef String<32> Name;
friend class Platform_pd;
Name const _name; /* name at kernel debugger */
State _state;
bool _core_thread;
Cap_mapping _thread;
Cap_mapping _gate { };
Cap_mapping _pager { };
Cap_mapping _irq;
addr_t _utcb;
Platform_pd *_platform_pd; /* protection domain thread is bound to */
Pager_object *_pager_obj;
unsigned _prio;
Affinity::Location _location { };
void _create_thread(void);
void _finalize_construction();
bool _in_syscall(Foc::l4_umword_t flags);
public:
enum { DEFAULT_PRIORITY = 128 };
/**
* Constructor for non-core threads
*/
Platform_thread(size_t, const char *name, unsigned priority,
Affinity::Location, addr_t);
/**
* Constructor for core main-thread
*/
Platform_thread(Core_cap_index& thread,
Core_cap_index& irq, const char *name);
/**
* Constructor for core threads
*/
Platform_thread(const char *name);
/**
* Destructor
*/
~Platform_thread();
/**
* Start thread
*
* \param ip instruction pointer to start at
* \param sp stack pointer to use
*
* \retval 0 successful
* \retval -1 thread could not be started
*/
int start(void *ip, void *sp);
/**
* 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 pd platform pd, thread is bound to
*/
void bind(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
*
* \throw Cpu_session::State_access_failed
*/
Foc_thread_state state();
/**
* Set the executing CPU for this thread
*/
void affinity(Affinity::Location location);
/**
* Get the executing CPU for this thread
*/
Affinity::Location affinity() const;
/**
* Make thread to vCPU
*/
Foc::l4_cap_idx_t setup_vcpu(unsigned, Cap_mapping const &, Cap_mapping &);
/************************
** Accessor functions **
************************/
/**
* Return/set pager
*/
Pager_object &pager() const
{
if (_pager_obj)
return *_pager_obj;
ASSERT_NEVER_CALLED;
}
void pager(Pager_object &pager);
/**
* Return identification of thread when faulting
*/
unsigned long pager_object_badge()
{
return (unsigned long) _thread.local.data()->kcap();
}
/**
* Set CPU quota of the thread to 'quota'
*/
void quota(size_t const) { /* not supported*/ }
/**
* Return execution time consumed by the thread
*/
Trace::Execution_time execution_time() const;
/**********************************
** Fiasco.OC-specific Accessors **
**********************************/
Cap_mapping const & thread() const { return _thread; }
Cap_mapping & gate() { return _gate; }
Name name() const { return _name; }
bool core_thread() const { return _core_thread; }
addr_t utcb() const { return _utcb; }
unsigned prio() const { return _prio; }
};
#endif /* _CORE__INCLUDE__PLATFORM_THREAD_H_ */

View File

@ -26,11 +26,8 @@
/* base-internal includes */
#include <base/internal/page_size.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/types.h>
#include <l4/sys/ktrace.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
namespace Genode {
@ -43,7 +40,7 @@ namespace Genode {
inline void touch_ro(const void *addr, unsigned size)
{
using namespace Fiasco;
using namespace Foc;
unsigned char const volatile *bptr;
unsigned char const *eptr;
@ -55,7 +52,8 @@ namespace Genode {
inline void touch_rw(const void *addr, unsigned size)
{
using namespace Fiasco;
using namespace Foc;
unsigned char volatile *bptr;
unsigned char const *eptr;
@ -65,8 +63,8 @@ namespace Genode {
touch_read_write(bptr);
}
inline addr_t trunc_page(addr_t addr) { return Fiasco::l4_trunc_page(addr); }
inline addr_t round_page(addr_t addr) { return Fiasco::l4_round_page(addr); }
inline addr_t trunc_page(addr_t addr) { return Foc::l4_trunc_page(addr); }
inline addr_t round_page(addr_t addr) { return Foc::l4_round_page(addr); }
constexpr size_t get_super_page_size() { return L4_SUPERPAGESIZE; }
constexpr size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; }

View File

@ -19,16 +19,16 @@
#include <base/heap.h>
#include <vm_session/vm_session.h>
/* Core includes */
/* core includes */
#include <cap_mapping.h>
#include <dataspace_component.h>
#include <region_map_component.h>
#include <trace/source_registry.h>
namespace Genode { class Vm_session_component; struct Vcpu; }
struct Genode::Vcpu : Genode::List<Vcpu>::Element
struct Genode::Vcpu : List<Vcpu>::Element
{
private:
@ -50,12 +50,13 @@ struct Genode::Vcpu : Genode::List<Vcpu>::Element
Cap_mapping &recall_cap() { return _recall; }
};
class Genode::Vm_session_component
:
private Ram_quota_guard,
private Cap_quota_guard,
public Rpc_object<Vm_session, Vm_session_component>,
public Region_map_detach
public Rpc_object<Vm_session, Vm_session_component>,
public Region_map_detach
{
private:
@ -88,6 +89,7 @@ class Genode::Vm_session_component
Trace::Source_registry &);
~Vm_session_component();
/*********************************
** Region_map_detach interface **
*********************************/
@ -95,6 +97,7 @@ class Genode::Vm_session_component
void detach(Region_map::Local_addr) override;
void unmap_region(addr_t, size_t) override;
/**************************
** Vm session interface **
**************************/

View File

@ -22,19 +22,21 @@
#include <base/internal/native_utcb.h>
#include <base/internal/cap_map.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/ipc.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
using namespace Genode;
using namespace Fiasco;
using namespace Foc;
void Ipc_pager::_parse(unsigned long label) {
void Ipc_pager::_parse(unsigned long label)
{
_badge = label & ~0x3;
_parse_msg_type();
if (_type == PAGEFAULT || _type == EXCEPTION)
_parse_pagefault();
if (_type == PAUSE || _type == EXCEPTION)
_regs = *l4_utcb_exc();
}
@ -96,12 +98,15 @@ void Ipc_pager::reply_and_wait_for_fault()
l4_utcb_mr()->mr[0] = _reply_mapping.dst_addr() | L4_ITEM_MAP | grant;
switch (_reply_mapping.cacheability()) {
case WRITE_COMBINED:
l4_utcb_mr()->mr[0] |= L4_FPAGE_BUFFERABLE << 4;
break;
case CACHED:
l4_utcb_mr()->mr[0] |= L4_FPAGE_CACHEABLE << 4;
break;
case UNCACHED:
if (!_reply_mapping.iomem())
l4_utcb_mr()->mr[0] |= L4_FPAGE_BUFFERABLE << 4;
@ -124,7 +129,7 @@ void Ipc_pager::reply_and_wait_for_fault()
void Ipc_pager::acknowledge_wakeup()
{
l4_cap_idx_t dst = Fiasco::Capability::valid(_last.kcap)
l4_cap_idx_t dst = Foc::Capability::valid(_last.kcap)
? _last.kcap : (l4_cap_idx_t)L4_SYSF_REPLY;
/* answer wakeup call from one of core's region-manager sessions */
@ -135,14 +140,14 @@ void Ipc_pager::acknowledge_wakeup()
void Ipc_pager::acknowledge_exception()
{
_regs = *l4_utcb_exc();
l4_cap_idx_t dst = Fiasco::Capability::valid(_last.kcap)
l4_cap_idx_t dst = Foc::Capability::valid(_last.kcap)
? _last.kcap : (l4_cap_idx_t)L4_SYSF_REPLY;
Fiasco::l4_msgtag_t const msg_tag =
Foc::l4_msgtag_t const msg_tag =
l4_ipc_send(dst, l4_utcb(),
l4_msgtag(0, L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0),
L4_IPC_SEND_TIMEOUT_0);
Fiasco::l4_umword_t const err = l4_ipc_error(msg_tag, l4_utcb());
Foc::l4_umword_t const err = l4_ipc_error(msg_tag, l4_utcb());
if (err) {
warning("failed to acknowledge exception, l4_ipc_err=", err);
}
@ -151,7 +156,7 @@ void Ipc_pager::acknowledge_exception()
Ipc_pager::Ipc_pager()
:
Native_capability((Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]),
Native_capability((Cap_index*)Foc::l4_utcb_tcr()->user[Foc::UTCB_TCR_BADGE]),
_badge(0)
{ }

View File

@ -25,18 +25,10 @@
#include <platform.h>
#include <util.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/icu.h>
#include <l4/sys/irq.h>
#include <l4/sys/factory.h>
#include <l4/sys/types.h>
}
namespace Genode {
class Interrupt_handler;
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
namespace Genode { class Interrupt_handler; }
using namespace Genode;
@ -58,7 +50,7 @@ class Genode::Interrupt_handler : public Thread
void entry() override;
static Fiasco::l4_cap_idx_t handler_cap()
static Foc::l4_cap_idx_t handler_cap()
{
static Interrupt_handler handler;
return handler._thread_cap.data()->kcap();
@ -68,35 +60,40 @@ class Genode::Interrupt_handler : public Thread
enum { MAX_MSIS = 256 };
static class Msi_allocator : public Genode::Bit_array<MAX_MSIS>
static struct Msi_allocator : Bit_array<MAX_MSIS>
{
public:
Msi_allocator()
{
using namespace Foc;
Msi_allocator() {
using namespace Fiasco;
l4_icu_info_t info { };
l4_icu_info_t info { .features = 0, .nr_irqs = 0, .nr_msis = 0 };
l4_msgtag_t res = l4_icu_info(Fiasco::L4_BASE_ICU_CAP, &info);
l4_msgtag_t const res = l4_icu_info(Foc::L4_BASE_ICU_CAP, &info);
if (l4_error(res) || !(info.features & L4_ICU_FLAG_MSI))
set(0, MAX_MSIS);
else
if (info.nr_msis < MAX_MSIS)
set(info.nr_msis, MAX_MSIS - info.nr_msis);
}
if (l4_error(res) || !(info.features & L4_ICU_FLAG_MSI))
set(0, MAX_MSIS);
else
if (info.nr_msis < MAX_MSIS)
set(info.nr_msis, MAX_MSIS - info.nr_msis);
}
} msi_alloc;
bool Genode::Irq_object::associate(unsigned irq, bool msi,
Irq_session::Trigger trigger,
Irq_session::Polarity polarity)
bool Irq_object::associate(unsigned irq, bool msi,
Irq_session::Trigger trigger,
Irq_session::Polarity polarity)
{
using namespace Fiasco;
using namespace Foc;
_irq = irq;
_trigger = trigger;
_polarity = polarity;
if (msi) irq |= L4_ICU_FLAG_MSI;
if (msi)
irq |= L4_ICU_FLAG_MSI;
else
/* set interrupt mode */
Platform::setup_irq_mode(irq, _trigger, _polarity);
@ -124,7 +121,7 @@ bool Genode::Irq_object::associate(unsigned irq, bool msi,
* Architecture Specification
*/
unsigned src_id = 0x0;
Fiasco::l4_icu_msi_info_t info = l4_icu_msi_info_t();
Foc::l4_icu_msi_info_t info = l4_icu_msi_info_t();
if (l4_error(l4_icu_msi_info(L4_BASE_ICU_CAP, irq,
src_id, &info))) {
error("cannot get MSI info");
@ -138,9 +135,9 @@ bool Genode::Irq_object::associate(unsigned irq, bool msi,
}
void Genode::Irq_object::ack_irq()
void Irq_object::ack_irq()
{
using namespace Fiasco;
using namespace Foc;
int err;
l4_msgtag_t tag = l4_irq_unmask(_capability());
@ -149,7 +146,7 @@ void Genode::Irq_object::ack_irq()
}
Genode::Irq_object::Irq_object()
Irq_object::Irq_object()
:
_cap(cap_map().insert(platform_specific().cap_id_alloc().alloc())),
_trigger(Irq_session::TRIGGER_UNCHANGED),
@ -158,15 +155,17 @@ Genode::Irq_object::Irq_object()
{ }
Genode::Irq_object::~Irq_object()
Irq_object::~Irq_object()
{
if (_irq == ~0U)
return;
using namespace Fiasco;
using namespace Foc;
unsigned long irq = _irq;
if (_msi_addr) irq |= L4_ICU_FLAG_MSI;
if (_msi_addr)
irq |= L4_ICU_FLAG_MSI;
if (l4_error(l4_irq_detach(_capability())))
error("cannot detach IRQ");
@ -182,13 +181,14 @@ Genode::Irq_object::~Irq_object()
** IRQ session component **
***************************/
Irq_session_component::Irq_session_component(Range_allocator &irq_alloc,
const char *args)
: _irq_number(Arg_string::find_arg(args, "irq_number").long_value(-1)),
_irq_alloc(irq_alloc), _irq_object()
:
_irq_number(Arg_string::find_arg(args, "irq_number").long_value(-1)),
_irq_alloc(irq_alloc), _irq_object()
{
long msi = Arg_string::find_arg(args, "device_config_phys").long_value(0);
long const msi = Arg_string::find_arg(args, "device_config_phys").long_value(0);
if (msi) {
if (msi_alloc.get(_irq_number, 1)) {
error("unavailable MSI ", _irq_number, " requested");
@ -203,6 +203,7 @@ Irq_session_component::Irq_session_component(Range_allocator &irq_alloc,
}
Irq_args const irq_args(args);
if (_irq_object.associate(_irq_number, msi, irq_args.trigger(),
irq_args.polarity()))
return;
@ -226,13 +227,16 @@ Irq_session_component::~Irq_session_component()
if (_irq_object.msi_address()) {
msi_alloc.clear(_irq_number, 1);
} else {
Genode::addr_t free_irq = _irq_number;
addr_t const free_irq = _irq_number;
_irq_alloc.free((void *)free_irq);
}
}
void Irq_session_component::ack_irq() { _irq_object.ack_irq(); }
void Irq_session_component::ack_irq()
{
_irq_object.ack_irq();
}
void Irq_session_component::sigh(Genode::Signal_context_capability cap)
@ -241,7 +245,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()
{
if (!_irq_object.msi_address())
return { .type = Info::Type::INVALID, .address = 0, .value = 0 };
@ -263,7 +267,7 @@ __attribute__((optimize("-fno-omit-frame-pointer")))
__attribute__((noinline))
void Interrupt_handler::entry()
{
using namespace Fiasco;
using namespace Foc;
int err;
l4_msgtag_t tag;

View File

@ -20,30 +20,23 @@
#include <platform.h>
/* Fiasco.OC includes */
namespace Fiasco {
#include <l4/sys/thread.h>
#include <l4/sys/factory.h>
}
#include <foc/syscall.h>
using namespace Genode;
Genode::Native_capability
Genode::Native_cpu_component::native_cap(Genode::Thread_capability cap)
Native_capability Native_cpu_component::native_cap(Thread_capability cap)
{
using namespace Genode;
auto lambda = [&] (Cpu_thread_component *thread) {
return (!thread) ? Native_capability()
: thread->platform_thread().thread().local;
};
: thread->platform_thread().thread().local; };
return _thread_ep.apply(cap, lambda);
}
Genode::Foc_thread_state
Genode::Native_cpu_component::thread_state(Genode::Thread_capability cap)
Foc_thread_state Native_cpu_component::thread_state(Thread_capability cap)
{
using namespace Genode;
auto lambda = [&] (Cpu_thread_component *thread) {
return (!thread) ? Foc_thread_state()
: thread->platform_thread().state(); };
@ -52,7 +45,7 @@ Genode::Native_cpu_component::thread_state(Genode::Thread_capability cap)
}
Genode::Native_cpu_component::Native_cpu_component(Cpu_session_component &cpu_session, char const *)
Native_cpu_component::Native_cpu_component(Cpu_session_component &cpu_session, char const *)
:
_cpu_session(cpu_session), _thread_ep(_cpu_session._thread_ep)
{
@ -60,7 +53,7 @@ Genode::Native_cpu_component::Native_cpu_component(Cpu_session_component &cpu_se
}
Genode::Native_cpu_component::~Native_cpu_component()
Native_cpu_component::~Native_cpu_component()
{
_thread_ep.dissolve(this);
}

View File

@ -1,5 +1,5 @@
/*
* \brief Fiasco pager framework
* \brief Fiasco.OC pager framework
* \author Norman Feske
* \author Christian Helmuth
* \author Stefan Kalkowski
@ -24,10 +24,7 @@
#include <base/internal/native_thread.h>
/* Fiasco.OC includes */
namespace Fiasco {
#include <l4/sys/factory.h>
#include <l4/sys/ipc.h>
}
#include <foc/syscall.h>
using namespace Genode;
@ -45,6 +42,7 @@ void Pager_entrypoint::entry()
reply_pending = false;
apply(_pager.badge(), [&] (Pager_object *obj) {
/* the pager_object might be destroyed, while we got the message */
if (!obj) {
warning("no pager object found!");
@ -149,7 +147,7 @@ void Pager_entrypoint::dissolve(Pager_object &obj)
Pager_capability Pager_entrypoint::manage(Pager_object &obj)
{
using namespace Fiasco;
using namespace Foc;
Native_capability cap(_cap_factory.alloc(Thread::_thread_cap));

View File

@ -18,16 +18,14 @@
#include <base/internal/cap_map.h>
/* Fiasco.OC includes */
namespace Fiasco {
#include <l4/sys/ipc.h>
}
#include <foc/syscall.h>
using namespace Genode;
void Pager_object::wake_up()
{
using namespace Fiasco;
using namespace Foc;
/*
* Issue IPC to pager, transmitting the pager-object pointer as 'IP'.

View File

@ -1,5 +1,5 @@
/*
* \brief Fiasco platform interface implementation
* \brief Fiasco.OC platform interface implementation
* \author Christian Helmuth
* \author Stefan Kalkowski
* \date 2006-04-11
@ -35,17 +35,8 @@
#include <platform_pd.h>
#include <util.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sigma0/sigma0.h>
#include <l4/sys/icu.h>
#include <l4/sys/ipc.h>
#include <l4/sys/kip>
#include <l4/sys/thread.h>
#include <l4/sys/types.h>
#include <l4/sys/utcb.h>
#include <l4/sys/scheduler.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
using namespace Genode;
@ -60,9 +51,12 @@ static Synced_range_allocator<Allocator_avl> &_core_address_ranges()
return _core_address_ranges;
}
enum { PAGER_STACK_ELEMENTS = 1024 };
static unsigned long _core_pager_stack[PAGER_STACK_ELEMENTS];
/**
* Core pager "service loop"
*/
@ -72,13 +66,14 @@ __attribute__((optimize("-fno-omit-frame-pointer")))
__attribute__((noinline))
static void _core_pager_loop()
{
using namespace Fiasco;
using namespace Foc;
bool send_reply = false;
l4_umword_t label;
l4_utcb_t *utcb = l4_utcb();
l4_msgtag_t snd_tag = l4_msgtag(0, 0, 0, 0);
l4_msgtag_t tag;
l4_utcb_t * const utcb = l4_utcb();
bool send_reply = false;
l4_umword_t label;
l4_msgtag_t snd_tag = l4_msgtag(0, 0, 0, 0);
l4_msgtag_t tag;
while (true) {
@ -93,9 +88,9 @@ static void _core_pager_loop()
}
/* read fault information */
l4_umword_t pfa = l4_trunc_page(l4_utcb_mr()->mr[0]);
l4_umword_t ip = l4_utcb_mr()->mr[1];
bool rw = l4_utcb_mr()->mr[0] & 2; //TODO enum
l4_umword_t const pfa = l4_trunc_page(l4_utcb_mr()->mr[0]);
l4_umword_t const ip = l4_utcb_mr()->mr[1];
bool const rw = l4_utcb_mr()->mr[0] & 2; //TODO enum
if (pfa < (l4_umword_t)L4_PAGESIZE) {
@ -156,7 +151,7 @@ Platform::Core_pager::Core_pager(Platform_pd &core_pd, Sigma0 &sigma0)
void *sp = (void *)&_core_pager_stack[PAGER_STACK_ELEMENTS - 1];
start((void *)_core_pager_loop, sp);
using namespace Fiasco;
using namespace Foc;
l4_thread_control_start();
l4_thread_control_pager(thread().local.data()->kcap());
@ -180,10 +175,10 @@ Platform::Core_pager &Platform::core_pager()
struct Region
{
addr_t start;
addr_t end;
addr_t start = 0;
addr_t end = 0;
Region() : start(0), end(0) { }
Region() { }
Region(addr_t s, addr_t e) : start(s), end(e) { }
/**
@ -202,8 +197,8 @@ struct Region
static inline void add_region(Region r, Range_allocator &alloc)
{
/* adjust region */
addr_t start = trunc_page(r.start);
addr_t end = round_page(r.end);
addr_t const start = trunc_page(r.start);
addr_t const end = round_page(r.end);
alloc.add_range(start, end - start);
}
@ -215,8 +210,8 @@ static inline void add_region(Region r, Range_allocator &alloc)
static inline void remove_region(Region r, Range_allocator &alloc)
{
/* adjust region */
addr_t start = trunc_page(r.start);
addr_t end = round_page(r.end);
addr_t const start = trunc_page(r.start);
addr_t const end = round_page(r.end);
alloc.remove_range(start, end - start);
}
@ -227,7 +222,7 @@ static inline void remove_region(Region r, Range_allocator &alloc)
*/
static inline int sigma0_req_region(addr_t *addr, unsigned log2size)
{
using namespace Fiasco;
using namespace Foc;
l4_utcb_mr()->mr[0] = SIGMA0_REQ_FPAGE_ANY;
l4_utcb_mr()->mr[1] = l4_fpage(0, log2size, 0).raw;
@ -251,13 +246,14 @@ static inline int sigma0_req_region(addr_t *addr, unsigned log2size)
}
static Fiasco::l4_kernel_info_t &sigma0_map_kip()
static Foc::l4_kernel_info_t &sigma0_map_kip()
{
using namespace Fiasco;
using namespace Foc;
static l4_kernel_info_t *kip_ptr = nullptr;
if (kip_ptr) return *kip_ptr;
if (kip_ptr)
return *kip_ptr;
/* signal we want to map the KIP */
l4_utcb_mr()->mr[0] = SIGMA0_REQ_KIP;
@ -268,14 +264,14 @@ static Fiasco::l4_kernel_info_t &sigma0_map_kip()
l4_utcb_br()->br[1] = l4_fpage(0, L4_WHOLE_ADDRESS_SPACE, L4_FPAGE_RX).raw;
/* call sigma0 */
l4_msgtag_t tag = l4_ipc_call(L4_BASE_PAGER_CAP,
l4_utcb(),
l4_msgtag(L4_PROTO_SIGMA0, 1, 0, 0),
L4_IPC_NEVER);
l4_msgtag_t const tag = l4_ipc_call(L4_BASE_PAGER_CAP,
l4_utcb(),
l4_msgtag(L4_PROTO_SIGMA0, 1, 0, 0),
L4_IPC_NEVER);
if (l4_ipc_error(tag, l4_utcb()))
panic("kip request to sigma0 failed");
l4_addr_t ret = l4_trunc_page(l4_utcb_mr()->mr[0]);
l4_addr_t const ret = l4_trunc_page(l4_utcb_mr()->mr[0]);
if (!ret)
panic("kip mapping failed");
@ -297,11 +293,12 @@ void Platform::_setup_mem_alloc()
for ( ; beg < end; beg += L4_PAGESIZE) (void)(*beg);
/* request pages of known page size starting with largest */
size_t log2_sizes[] = { L4_LOG2_SUPERPAGESIZE, L4_LOG2_PAGESIZE };
size_t const log2_sizes[] = { L4_LOG2_SUPERPAGESIZE, L4_LOG2_PAGESIZE };
for (unsigned i = 0; i < sizeof(log2_sizes)/sizeof(*log2_sizes); ++i) {
size_t log2_size = log2_sizes[i];
size_t size = 1UL << log2_size;
size_t const log2_size = log2_sizes[i];
size_t const size = 1UL << log2_size;
int err = 0;
addr_t addr = 0;
Region region;
@ -312,10 +309,10 @@ void Platform::_setup_mem_alloc()
if (!err) {
/* XXX do not allocate page0 */
if (addr == 0) {
Fiasco::l4_task_unmap(Fiasco::L4_BASE_TASK_CAP,
Fiasco::l4_fpage(0, log2_size,
Fiasco::L4_FPAGE_RW),
Fiasco::L4_FP_ALL_SPACES);
Foc::l4_task_unmap(Foc::L4_BASE_TASK_CAP,
Foc::l4_fpage(0, log2_size,
Foc::L4_FPAGE_RW),
Foc::L4_FP_ALL_SPACES);
continue;
}
@ -335,10 +332,10 @@ void Platform::_setup_mem_alloc()
void Platform::_setup_irq_alloc()
{
using namespace Fiasco;
using namespace Foc;
l4_icu_info_t info { .features = 0, .nr_irqs = 0, .nr_msis = 0 };
l4_msgtag_t res = l4_icu_info(Fiasco::L4_BASE_ICU_CAP, &info);
l4_msgtag_t res = l4_icu_info(Foc::L4_BASE_ICU_CAP, &info);
if (l4_error(res))
panic("could not determine number of IRQs");
@ -348,7 +345,7 @@ void Platform::_setup_irq_alloc()
void Platform::_setup_basics()
{
using namespace Fiasco;
using namespace Foc;
l4_kernel_info_t const &kip = sigma0_map_kip();
@ -364,12 +361,12 @@ void Platform::_setup_basics()
_rom_fs.insert(&_kip_rom);
/* update multi-boot info pointer from KIP */
addr_t mb_info_addr = kip.user_ptr;
addr_t const mb_info_addr = kip.user_ptr;
log("MBI @ ", Hex(mb_info_addr));
/* parse memory descriptors - look for virtual memory configuration */
/* XXX we support only one VM region (here and also inside RM) */
using Fiasco::L4::Kip::Mem_desc;
using Foc::L4::Kip::Mem_desc;
_vm_start = 0; _vm_size = 0;
Mem_desc const * const desc = Mem_desc::first(&kip);
@ -385,8 +382,8 @@ void Platform::_setup_basics()
panic("Virtual memory configuration not found");
/* configure applicable address space but never use page0 */
_vm_size = _vm_start == 0 ? _vm_size - L4_PAGESIZE : _vm_size;
_vm_start = _vm_start == 0 ? L4_PAGESIZE : _vm_start;
_vm_size = (_vm_start == 0 ? _vm_size - L4_PAGESIZE : _vm_size);
_vm_start = (_vm_start == 0 ? L4_PAGESIZE : _vm_start);
/* reserve virtual range for extended vCPU features - better way XXX ? */
if (_vm_start < VCPU_VIRT_EXT_END) {
@ -412,8 +409,8 @@ void Platform::_setup_basics()
remove_region(Region((addr_t)&kip, (addr_t)&kip + L4_PAGESIZE), _io_mem_alloc);
/* remove core program image memory from region and IO_MEM allocator */
addr_t img_start = (addr_t) &_prog_img_beg;
addr_t img_end = (addr_t) &_prog_img_end;
addr_t const img_start = (addr_t) &_prog_img_beg;
addr_t const img_end = (addr_t) &_prog_img_end;
remove_region(Region(img_start, img_end), _region_alloc);
remove_region(Region(img_start, img_end), _io_mem_alloc);
@ -422,18 +419,22 @@ void Platform::_setup_basics()
}
Platform::Platform() :
Platform::Platform()
:
_ram_alloc(nullptr), _io_mem_alloc(&core_mem_alloc()),
_io_port_alloc(&core_mem_alloc()), _irq_alloc(&core_mem_alloc()),
_region_alloc(&core_mem_alloc()), _cap_id_alloc(core_mem_alloc()),
_kip_rom((addr_t)&sigma0_map_kip(), L4_PAGESIZE, "l4v2_kip"),
_sigma0(cap_map().insert(_cap_id_alloc.alloc(), Fiasco::L4_BASE_PAGER_CAP))
_sigma0(cap_map().insert(_cap_id_alloc.alloc(), Foc::L4_BASE_PAGER_CAP))
{
/*
* We must be single-threaded at this stage and so this is safe.
*/
static bool initialized = 0;
if (initialized) panic("Platform constructed twice!");
if (initialized)
panic("Platform constructed twice!");
initialized = true;
_setup_basics();
@ -446,10 +447,10 @@ Platform::Platform() :
Core_cap_index &pdi =
*reinterpret_cast<Core_cap_index*>(cap_map().insert(_cap_id_alloc.alloc(),
Fiasco::L4_BASE_TASK_CAP));
Foc::L4_BASE_TASK_CAP));
Core_cap_index &thi =
*reinterpret_cast<Core_cap_index*>(cap_map().insert(_cap_id_alloc.alloc(),
Fiasco::L4_BASE_THREAD_CAP));
Foc::L4_BASE_THREAD_CAP));
Core_cap_index &irqi =
*reinterpret_cast<Core_cap_index*>(cap_map().insert(_cap_id_alloc.alloc()));
@ -476,10 +477,11 @@ Platform::Platform() :
if (ram_alloc().alloc_aligned(size, &phys_ptr, align).error())
return;
if (region_alloc().alloc_aligned(size, &core_local_ptr, align).error())
return;
addr_t const phys_addr = reinterpret_cast<addr_t>(phys_ptr);
addr_t const phys_addr = reinterpret_cast<addr_t>(phys_ptr);
addr_t const core_local_addr = reinterpret_cast<addr_t>(core_local_ptr);
if (!map_local(phys_addr, core_local_addr, pages))
@ -487,18 +489,17 @@ Platform::Platform() :
memset(core_local_ptr, 0, size);
Genode::Xml_generator xml(reinterpret_cast<char *>(core_local_addr),
pages << get_page_size_log2(),
"platform_info", [&] ()
Xml_generator xml(reinterpret_cast<char *>(core_local_addr),
pages << get_page_size_log2(),
"platform_info", [&] ()
{
xml.node("kernel", [&] () { xml.attribute("name", "foc"); });
xml.node("hardware", [&] () {
_setup_platform_info(xml, sigma0_map_kip());
});
_setup_platform_info(xml, sigma0_map_kip()); });
xml.node("affinity-space", [&] () {
xml.attribute("width", affinity_space().width());
xml.attribute("height", affinity_space().height());
});
xml.attribute("height", affinity_space().height()); });
});
_rom_fs.insert(new (core_mem_alloc()) Rom_module(phys_addr, size,
@ -533,6 +534,7 @@ Platform::Platform() :
}
Affinity::Space const cpus = affinity_space();
for (unsigned cpu_id = 0; cpu_id < cpus.width(); cpu_id++)
{
struct Trace_source : public Trace::Source::Info_accessor,
@ -540,7 +542,7 @@ Platform::Platform() :
private Trace::Source
{
Affinity::Location const affinity;
Genode::String<8> const name;
String<8> const name;
/**
* Trace::Source::Info_accessor interface
@ -550,7 +552,7 @@ Platform::Platform() :
uint64_t ec_time = 0;
uint64_t const sc_time = 0;
using namespace Fiasco;
using namespace Foc;
l4_sched_cpu_set_t const cpu = l4_sched_cpu_set(affinity.xpos(), 0);
l4_msgtag_t const res = l4_scheduler_idle_time(L4_BASE_SCHEDULER_CAP,
&cpu, &ec_time);
@ -589,7 +591,7 @@ Platform::Platform() :
void Platform::wait_for_exit()
{
/*
* On Fiasco, Core never exits. So let us sleep forever.
* On Fiasco.OC, core never exits. So let us sleep forever.
*/
sleep_forever();
}
@ -597,8 +599,7 @@ void Platform::wait_for_exit()
Affinity::Space Platform::affinity_space() const
{
using namespace Genode;
using namespace Fiasco;
using namespace Foc;
l4_sched_cpu_set_t cpus = l4_sched_cpu_set(0, 0, 1);
l4_umword_t cpus_max;

View File

@ -1,5 +1,5 @@
/*
* \brief Fiasco protection domain facility
* \brief Fiasco.OC protection domain facility
* \author Christian Helmuth
* \author Stefan Kalkowski
* \date 2006-04-11
@ -22,17 +22,15 @@
#include <platform_pd.h>
#include <map_local.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/utcb.h>
#include <l4/sys/factory.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
using namespace Fiasco;
using namespace Foc;
using namespace Genode;
static addr_t core_utcb_base() {
static addr_t core_utcb_base()
{
static addr_t base = (addr_t) l4_utcb();
return base;
}
@ -49,9 +47,11 @@ bool Platform_pd::bind_thread(Platform_thread &thread)
* number of threads is limited to 16K / L4_UTCB_OFFSET.
* (see kernel/fiasco/src/kern/kernel_thread-std.cpp:94)
*/
unsigned const thread_max = thread.core_thread() ? 16*1024/L4_UTCB_OFFSET : THREAD_MAX;
unsigned const thread_max = thread.core_thread()
? 16*1024/L4_UTCB_OFFSET : THREAD_MAX;
for (unsigned i = 0; i < thread_max; i++) {
if (_threads[i])
continue;
@ -63,7 +63,7 @@ bool Platform_pd::bind_thread(Platform_thread &thread)
thread._utcb =
reinterpret_cast<addr_t>(utcb_area_start() + i * L4_UTCB_OFFSET);
Fiasco::l4_cap_idx_t cap_offset = THREAD_AREA_BASE + i * THREAD_AREA_SLOT;
Foc::l4_cap_idx_t cap_offset = THREAD_AREA_BASE + i * THREAD_AREA_SLOT;
thread._gate.remote = cap_offset + THREAD_GATE_CAP;
thread._pager.remote = cap_offset + THREAD_PAGER_CAP;
@ -106,7 +106,7 @@ void Platform_pd::unbind_thread(Platform_thread &thread)
void Platform_pd::assign_parent(Native_capability parent)
{
if (_parent.remote == Fiasco::L4_INVALID_CAP && parent.valid()) {
if (_parent.remote == Foc::L4_INVALID_CAP && parent.valid()) {
_parent.local = parent;
_parent.remote = PARENT_CAP;
_parent.map(_task.local.data()->kcap());
@ -129,17 +129,21 @@ static Native_capability debug_cap()
}
Platform_pd::Platform_pd(Core_cap_index &ci)
: _task(Native_capability(&ci), TASK_CAP)
:
_task(Native_capability(&ci), TASK_CAP)
{ }
Platform_pd::Platform_pd(Allocator &, char const *)
: _task(true, TASK_CAP), _debug(debug_cap(), DEBUG_CAP)
:
_task(true, TASK_CAP), _debug(debug_cap(), DEBUG_CAP)
{
l4_fpage_t utcb_area = l4_fpage(utcb_area_start(),
log2<unsigned>(UTCB_AREA_SIZE), 0);
l4_msgtag_t tag = l4_factory_create_task(L4_BASE_FACTORY_CAP,
_task.local.data()->kcap(), utcb_area);
l4_fpage_t const utcb_area = l4_fpage(utcb_area_start(),
log2<unsigned>(UTCB_AREA_SIZE), 0);
l4_msgtag_t const tag = l4_factory_create_task(L4_BASE_FACTORY_CAP,
_task.local.data()->kcap(),
utcb_area);
if (l4_msgtag_has_error(tag))
error("pd creation failed");
}
@ -147,8 +151,7 @@ Platform_pd::Platform_pd(Allocator &, char const *)
Platform_pd::~Platform_pd()
{
for (unsigned i = 0; i < THREAD_MAX; i++) {
for (unsigned i = 0; i < THREAD_MAX; i++)
if (_threads[i])
_threads[i]->unbind();
}
}

View File

@ -1,5 +1,5 @@
/*
* \brief Fiasco thread facility
* \brief Fiasco.OC thread facility
* \author Stefan Kalkowski
* \date 2011-01-04
*/
@ -22,22 +22,16 @@
#include <platform.h>
#include <core_env.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/debugger.h>
#include <l4/sys/factory.h>
#include <l4/sys/irq.h>
#include <l4/sys/scheduler.h>
#include <l4/sys/thread.h>
#include <l4/sys/types.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
using namespace Genode;
using namespace Fiasco;
using namespace Foc;
Trace::Execution_time Platform_thread::execution_time() const
{
Fiasco::l4_kernel_clock_t us = 0;
Foc::l4_kernel_clock_t us = 0;
l4_thread_stats_time(_thread.local.data()->kcap(), &us);
return { us, 0, 10000 /* quantum readable ?*/, _prio };
}
@ -98,10 +92,11 @@ void Platform_thread::pause()
Foc_thread_state &reg_state = _pager_obj->state.state;
unsigned exc = _pager_obj->state.exceptions;
reg_state.ip = ~0UL;
reg_state.sp = ~0UL;
l4_umword_t flags = L4_THREAD_EX_REGS_TRIGGER_EXCEPTION;
reg_state.ip = ~0UL;
reg_state.sp = ~0UL;
unsigned const exc = _pager_obj->state.exceptions;
l4_umword_t flags = L4_THREAD_EX_REGS_TRIGGER_EXCEPTION;
/* Mark thread to be stopped */
_pager_obj->state.paused = true;
@ -117,7 +112,8 @@ void Platform_thread::pause()
/*
* The thread state ("ready") is encoded in the lowest bit of the flags.
*/
bool in_syscall = (flags & 1) == 0;
bool const in_syscall = (flags & 1) == 0;
_pager_obj->state.mutex.release();
/**
@ -137,12 +133,12 @@ void Platform_thread::pause()
void Platform_thread::single_step(bool enabled)
{
Fiasco::l4_cap_idx_t const tid = thread().local.data()->kcap();
Foc::l4_cap_idx_t const tid = thread().local.data()->kcap();
enum { THREAD_SINGLE_STEP = 0x40000 };
int const flags = enabled ? THREAD_SINGLE_STEP : 0;
Fiasco::l4_thread_ex_regs(tid, ~0UL, ~0UL, flags);
Foc::l4_thread_ex_regs(tid, ~0UL, ~0UL, flags);
}
@ -157,7 +153,7 @@ void Platform_thread::resume()
_pager_obj->state.paused = false;
_pager_obj->state.mutex.release();
/* Send a message to the exception handler, to unblock the client */
/* send a message to the exception handler, to unblock the client */
Msgbuf<16> snd, rcv;
snd.insert(_pager_obj);
ipc_call(_pager_obj->cap(), snd, rcv, 0);
@ -168,7 +164,7 @@ void Platform_thread::bind(Platform_pd &pd)
{
_platform_pd = &pd;
_gate.map(pd.native_task().data()->kcap());
_irq.map(pd.native_task().data()->kcap());
_irq .map(pd.native_task().data()->kcap());
}
@ -211,7 +207,8 @@ void Platform_thread::state(Thread_state s)
Foc_thread_state Platform_thread::state()
{
Foc_thread_state s;
if (_pager_obj) s = _pager_obj->state.state;
if (_pager_obj)
s = _pager_obj->state.state;
s.kcap = _gate.remote;
s.id = _gate.local.local_name();
@ -273,7 +270,7 @@ void Platform_thread::_finalize_construction()
warning("attaching thread's irq failed");
/* set human readable name in kernel debugger */
Fiasco::l4_debugger_set_object_name(_thread.local.data()->kcap(), _name.string());
Foc::l4_debugger_set_object_name(_thread.local.data()->kcap(), _name.string());
/* set priority of thread */
l4_sched_param_t params = l4_sched_param(_prio);
@ -284,15 +281,16 @@ void Platform_thread::_finalize_construction()
Platform_thread::Platform_thread(size_t, const char *name, unsigned prio,
Affinity::Location location, addr_t)
: _name(name),
_state(DEAD),
_core_thread(false),
_thread(true),
_irq(true),
_utcb(0),
_platform_pd(0),
_pager_obj(0),
_prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, prio))
:
_name(name),
_state(DEAD),
_core_thread(false),
_thread(true),
_irq(true),
_utcb(0),
_platform_pd(0),
_pager_obj(0),
_prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, prio))
{
/* XXX remove const cast */
((Core_cap_index *)_thread.local.data())->pt(this);
@ -304,34 +302,34 @@ Platform_thread::Platform_thread(size_t, const char *name, unsigned prio,
Platform_thread::Platform_thread(Core_cap_index &thread,
Core_cap_index &irq, const char *name)
: _name(name),
_state(RUNNING),
_core_thread(true),
_thread(Native_capability(&thread), L4_BASE_THREAD_CAP),
_irq(Native_capability(&irq)),
_utcb(0),
_platform_pd(0),
_pager_obj(0),
_prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, 0))
:
_name(name),
_state(RUNNING),
_core_thread(true),
_thread(Native_capability(&thread), L4_BASE_THREAD_CAP),
_irq(Native_capability(&irq)),
_utcb(0),
_platform_pd(0),
_pager_obj(0),
_prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, 0))
{
/* XXX remove const cast */
((Core_cap_index *)_thread.local.data())->pt(this);
_finalize_construction();
}
Platform_thread::Platform_thread(const char *name)
: _name(name),
_state(DEAD),
_core_thread(true),
_thread(true),
_irq(true),
_utcb(0),
_platform_pd(0),
_pager_obj(0),
_prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, 0))
:
_name(name),
_state(DEAD),
_core_thread(true),
_thread(true),
_irq(true),
_utcb(0),
_platform_pd(0),
_pager_obj(0),
_prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, 0))
{
/* XXX remove const cast */
((Core_cap_index *)_thread.local.data())->pt(this);
_create_thread();
_finalize_construction();
@ -343,36 +341,36 @@ Platform_thread::~Platform_thread()
thread_cap_factory().free(_gate.local);
/*
* We inform our protection domain about thread destruction, which will end up in
* Thread::unbind()
* We inform our protection domain about thread destruction, which will end
* up in Thread::unbind()
*/
if (_platform_pd)
_platform_pd->unbind_thread(*this);
}
Fiasco::l4_cap_idx_t Platform_thread::setup_vcpu(unsigned const vcpu_id,
Foc::l4_cap_idx_t Platform_thread::setup_vcpu(unsigned const vcpu_id,
Cap_mapping const &task_vcpu,
Cap_mapping &vcpu_irq)
{
if (!_platform_pd)
return Fiasco::L4_INVALID_CAP;
if (vcpu_id >= (Platform::VCPU_VIRT_EXT_END - Platform::VCPU_VIRT_EXT_START) / L4_PAGESIZE)
return Fiasco::L4_INVALID_CAP;
return Foc::L4_INVALID_CAP;
Genode::addr_t const vcpu_addr = Platform::VCPU_VIRT_EXT_START +
L4_PAGESIZE * vcpu_id;
l4_fpage_t vm_page = l4_fpage( vcpu_addr, L4_PAGESHIFT, L4_FPAGE_RW);
if (vcpu_id >= (Platform::VCPU_VIRT_EXT_END - Platform::VCPU_VIRT_EXT_START) / L4_PAGESIZE)
return Foc::L4_INVALID_CAP;
addr_t const vcpu_addr = Platform::VCPU_VIRT_EXT_START + L4_PAGESIZE*vcpu_id;
l4_fpage_t const vm_page = l4_fpage( vcpu_addr, L4_PAGESHIFT, L4_FPAGE_RW);
l4_msgtag_t msg = l4_task_add_ku_mem(_platform_pd->native_task().data()->kcap(), vm_page);
if (l4_error(msg)) {
Genode::error("ku_mem failed ", l4_error(msg));
return Fiasco::L4_INVALID_CAP;
error("ku_mem failed ", l4_error(msg));
return Foc::L4_INVALID_CAP;
}
msg = l4_thread_vcpu_control_ext(_thread.local.data()->kcap(), vcpu_addr);
if (l4_error(msg)) {
Genode::error("vcpu_control_exit failed ", l4_error(msg));
return Fiasco::L4_INVALID_CAP;
error("vcpu_control_exit failed ", l4_error(msg));
return Foc::L4_INVALID_CAP;
}
/* attach thread to irq */

View File

@ -15,13 +15,15 @@
#include <ram_dataspace_factory.h>
#include <map_local.h>
namespace Fiasco {
#include <l4/sys/cache.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
using namespace Genode;
void Ram_dataspace_factory::_export_ram_ds(Dataspace_component &) { }
void Ram_dataspace_factory::_revoke_ram_ds(Dataspace_component &) { }
@ -30,6 +32,6 @@ void Ram_dataspace_factory::_clear_ds(Dataspace_component &ds)
memset((void *)ds.phys_addr(), 0, ds.size());
if (ds.cacheability() != CACHED)
Fiasco::l4_cache_dma_coherent(ds.phys_addr(), ds.phys_addr() + ds.size());
Foc::l4_cache_dma_coherent(ds.phys_addr(), ds.phys_addr() + ds.size());
}

View File

@ -26,14 +26,8 @@
#include <base/internal/cap_alloc.h>
#include <base/internal/foc_assert.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/consts.h>
#include <l4/sys/debugger.h>
#include <l4/sys/factory.h>
#include <l4/sys/task.h>
#include <l4/sys/types.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
using namespace Genode;
@ -42,9 +36,9 @@ using namespace Genode;
** Cap_index_allocator **
***************************/
Genode::Cap_index_allocator &Genode::cap_idx_alloc()
Cap_index_allocator &Genode::cap_idx_alloc()
{
static Genode::Cap_index_allocator_tpl<Core_cap_index,10*1024> alloc;
static Cap_index_allocator_tpl<Core_cap_index,10*1024> alloc;
return alloc;
}
@ -60,11 +54,11 @@ Core_cap_index *Cap_mapping::_get_cap()
}
void Cap_mapping::map(Fiasco::l4_cap_idx_t task)
void Cap_mapping::map(Foc::l4_cap_idx_t task)
{
using namespace Fiasco;
using namespace Foc;
if (!local.valid() || !Fiasco::Capability::valid(remote))
if (!local.valid() || !Foc::Capability::valid(remote))
return;
l4_msgtag_t tag = l4_task_map(task, L4_BASE_TASK_CAP,
@ -75,12 +69,16 @@ void Cap_mapping::map(Fiasco::l4_cap_idx_t task)
}
Cap_mapping::Cap_mapping(bool alloc, Fiasco::l4_cap_idx_t r)
: local(alloc ? _get_cap() : (Native_capability::Data *)nullptr), remote(r) { }
Cap_mapping::Cap_mapping(bool alloc, Foc::l4_cap_idx_t r)
:
local(alloc ? _get_cap() : (Native_capability::Data *)nullptr), remote(r)
{ }
Cap_mapping::Cap_mapping(Native_capability cap, Fiasco::l4_cap_idx_t r)
: local(cap), remote(r) { }
Cap_mapping::Cap_mapping(Native_capability cap, Foc::l4_cap_idx_t r)
:
local(cap), remote(r)
{ }
/***********************
@ -97,7 +95,7 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep)
}
try {
using namespace Fiasco;
using namespace Foc;
Core_cap_index const * ref = static_cast<Core_cap_index const*>(ep.data());
@ -123,11 +121,13 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep)
cap_map().remove(idx);
platform_specific().cap_id_alloc().free(id);
return cap;
} else
/* set debugger-name of ipc-gate to thread's name */
Fiasco::l4_debugger_set_object_name(idx->kcap(), ref->pt()->name().string());
// XXX remove cast
} else {
/* set debugger-name of ipc-gate to thread's name */
Foc::l4_debugger_set_object_name(idx->kcap(), ref->pt()->name().string());
}
idx->session((Pd_session_component *)this);
idx->pt(ref->pt());
cap = Native_capability(idx);
@ -144,38 +144,41 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep)
*/
if (cap.valid())
_pool.insert(new (_entry_slab) Entry(cap));
return cap;
}
void Rpc_cap_factory::free(Native_capability cap)
{
using namespace Fiasco;
using namespace Foc;
if (!cap.valid()) return;
if (!cap.valid())
return;
/* check whether the capability was created by this cap_session */
if (static_cast<Core_cap_index const *>(cap.data())->session() != (Pd_session_component *)this)
return;
Entry * entry = nullptr;
_pool.apply(cap, [&] (Entry *e) {
entry = e;
if (e) {
_pool.remove(e);
Entry * entry_ptr = nullptr;
_pool.apply(cap, [&] (Entry *ptr) {
entry_ptr = ptr;
if (ptr) {
_pool.remove(ptr);
} else
warning("Could not find capability to be deleted");
});
if (entry) destroy(_entry_slab, entry);
if (entry_ptr)
destroy(_entry_slab, entry_ptr);
}
Rpc_cap_factory::~Rpc_cap_factory()
{
_pool.remove_all([this] (Entry *e) {
if (!e) return;
destroy(_entry_slab, e);
});
_pool.remove_all([this] (Entry *ptr) {
if (ptr)
destroy(_entry_slab, ptr); });
}
@ -184,7 +187,8 @@ Rpc_cap_factory::~Rpc_cap_factory()
*******************************/
Cap_id_allocator::Cap_id_allocator(Allocator &alloc)
: _id_alloc(&alloc)
:
_id_alloc(&alloc)
{
_id_alloc.add_range(CAP_ID_OFFSET, CAP_ID_RANGE);
}
@ -197,6 +201,7 @@ unsigned long Cap_id_allocator::alloc()
void *id = nullptr;
if (_id_alloc.alloc(CAP_ID_OFFSET, &id))
return (unsigned long) id;
throw Out_of_ids();
}
@ -210,15 +215,16 @@ void Cap_id_allocator::free(unsigned long id)
}
void Genode::Capability_map::remove(Genode::Cap_index *i)
void Capability_map::remove(Cap_index *i)
{
using namespace Genode;
using namespace Fiasco;
using namespace Foc;
Lock_guard<Spin_lock> guard(_lock);
if (i) {
Core_cap_index* e = static_cast<Core_cap_index*>(_tree.first() ? _tree.first()->find_by_id(i->id()) : 0);
Core_cap_index* e = static_cast<Core_cap_index*>(_tree.first()
? _tree.first()->find_by_id(i->id()) : nullptr);
if (e == i) {
l4_msgtag_t tag = l4_task_unmap(L4_BASE_TASK_CAP,
l4_obj_fpage(i->kcap(), 0, L4_FPAGE_RWX),
@ -226,7 +232,6 @@ void Genode::Capability_map::remove(Genode::Cap_index *i)
if (l4_msgtag_has_error(tag))
error("destruction of ipc-gate ", i->kcap(), " failed!");
platform_specific().cap_id_alloc().free(i->id());
_tree.remove(i);
}

View File

@ -20,10 +20,8 @@
#include <platform.h>
#include <signal_source_component.h>
namespace Fiasco {
#include <l4/sys/factory.h>
#include <l4/sys/irq.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
using namespace Genode;
@ -38,6 +36,7 @@ void Signal_source_component::release(Signal_context_component &context)
_signal_queue.remove(context);
}
void Signal_source_component::submit(Signal_context_component &context,
unsigned long cnt)
{
@ -48,7 +47,7 @@ void Signal_source_component::submit(Signal_context_component &context,
_signal_queue.enqueue(context);
/* wake up client */
Fiasco::l4_irq_trigger(_blocking_semaphore.data()->kcap());
Foc::l4_irq_trigger(_blocking_semaphore.data()->kcap());
}
}
@ -75,7 +74,7 @@ Signal_source_component::Signal_source_component(Rpc_entrypoint &ep)
Signal_source_rpc_object(cap_map().insert(platform_specific().cap_id_alloc().alloc())),
_entrypoint(ep)
{
using namespace Fiasco;
using namespace Foc;
l4_msgtag_t res = l4_factory_create_irq(L4_BASE_FACTORY_CAP,
_blocking_semaphore.data()->kcap());

View File

@ -16,23 +16,22 @@
/* core includes */
#include <ipc_pager.h>
namespace Fiasco {
#include <l4/sys/utcb.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
using namespace Genode;
enum Exceptions { EX_REGS = 0x500000 };
void Genode::Ipc_pager::_parse_exception()
void Ipc_pager::_parse_exception()
{
if (Fiasco::l4_utcb_exc()->err == EX_REGS)
_type = PAUSE;
else
_type = EXCEPTION;
_type = (Foc::l4_utcb_exc()->err == EX_REGS) ? PAUSE : EXCEPTION;
}
void Genode::Ipc_pager::get_regs(Foc_thread_state &state) const
void Ipc_pager::get_regs(Foc_thread_state &state) const
{
state.ip = _regs.pc;
state.sp = _regs.sp;
@ -54,7 +53,7 @@ void Genode::Ipc_pager::get_regs(Foc_thread_state &state) const
}
void Genode::Ipc_pager::set_regs(Foc_thread_state const &state)
void Ipc_pager::set_regs(Foc_thread_state const &state)
{
_regs.pc = state.ip;
_regs.sp = state.sp;
@ -75,7 +74,8 @@ void Genode::Ipc_pager::set_regs(Foc_thread_state const &state)
_regs.cpsr = state.cpsr;
}
bool Genode::Ipc_pager::exec_fault() const
bool Ipc_pager::exec_fault() const
{
return (_pf_addr & 4) && !(_pf_addr & 1);
}

View File

@ -13,9 +13,14 @@
#include <platform.h>
void Genode::Platform::_setup_io_port_alloc() { }
using namespace Genode;
void Genode::Platform::setup_irq_mode(unsigned, unsigned, unsigned) { }
void Genode::Platform::_setup_platform_info(Xml_generator &,
Fiasco::l4_kernel_info_t &) { }
void Platform::_setup_io_port_alloc() { }
void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { }
void Platform::_setup_platform_info(Xml_generator &,
Foc::l4_kernel_info_t &) { }

View File

@ -16,36 +16,35 @@
/* core includes */
#include <ipc_pager.h>
namespace Fiasco {
#include <l4/sys/utcb.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
using namespace Genode;
enum Exceptions { EX_REGS = 0x500000 };
void Genode::Ipc_pager::_parse_exception()
void Ipc_pager::_parse_exception()
{
if (Fiasco::l4_utcb_exc()->err == EX_REGS)
_type = PAUSE;
else
_type = EXCEPTION;
_type = (Foc::l4_utcb_exc()->err == EX_REGS) ? PAUSE : EXCEPTION;
}
void Genode::Ipc_pager::get_regs(Foc_thread_state &state) const
void Ipc_pager::get_regs(Foc_thread_state &state) const
{
state.ip = _regs.pc;
state.sp = _regs.sp;
state.ip = _regs.pc;
state.sp = _regs.sp;
}
void Genode::Ipc_pager::set_regs(Foc_thread_state const &state)
void Ipc_pager::set_regs(Foc_thread_state const &state)
{
_regs.pc = state.ip;
_regs.sp = state.sp;
_regs.pc = state.ip;
_regs.sp = state.sp;
}
bool Genode::Ipc_pager::exec_fault() const
bool Ipc_pager::exec_fault() const
{
return (_pf_addr & 4) && !(_pf_addr & 1);
}

View File

@ -14,20 +14,22 @@
/* core includes */
#include <ipc_pager.h>
namespace Fiasco {
#include <l4/sys/utcb.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
using namespace Genode;
enum Exceptions { EX_REGS = 0xff };
void Genode::Ipc_pager::_parse_exception()
void Ipc_pager::_parse_exception()
{
if (Fiasco::l4_utcb_exc()->trapno == EX_REGS)
_type = PAUSE;
else
_type = EXCEPTION;
_type = (Foc::l4_utcb_exc()->trapno == EX_REGS) ? PAUSE : EXCEPTION;
}
bool Genode::Ipc_pager::exec_fault() const {
return ((_pf_addr & 1) && !write_fault()); }
bool Ipc_pager::exec_fault() const
{
return ((_pf_addr & 1) && !write_fault());
}

View File

@ -21,24 +21,25 @@
#include "util.h"
/* Fiasco.OC includes */
namespace Fiasco {
#include <l4/sys/ipc.h>
#include <l4/sys/icu.h>
#include <l4/sys/kip.h>
}
#include <foc/syscall.h>
void Genode::Platform::_setup_io_port_alloc()
using namespace Genode;
void Platform::_setup_io_port_alloc()
{
using namespace Fiasco;
using namespace Foc;
l4_fpage_t const fpage = l4_iofpage(0, L4_WHOLE_IOADDRESS_SPACE);
l4_fpage_t fpage = l4_iofpage(0, L4_WHOLE_IOADDRESS_SPACE);
l4_utcb_mr()->mr[0] = fpage.raw;
l4_utcb_br()->bdr &= ~L4_BDR_OFFSET_MASK;
l4_utcb_br()->br[0] = L4_ITEM_MAP;
l4_utcb_br()->br[1] = fpage.raw;
l4_msgtag_t tag = l4_ipc_call(L4_BASE_PAGER_CAP, l4_utcb(),
l4_msgtag(L4_PROTO_IO_PAGE_FAULT, 1, 0, 0),
L4_IPC_NEVER);
l4_msgtag_t const tag = l4_ipc_call(L4_BASE_PAGER_CAP, l4_utcb(),
l4_msgtag(L4_PROTO_IO_PAGE_FAULT, 1, 0, 0),
L4_IPC_NEVER);
if (l4_ipc_error(tag, l4_utcb()))
panic("Received no I/O ports from sigma0");
@ -48,10 +49,10 @@ void Genode::Platform::_setup_io_port_alloc()
}
void Genode::Platform::setup_irq_mode(unsigned irq_number, unsigned trigger,
unsigned polarity)
void Platform::setup_irq_mode(unsigned irq_number, unsigned trigger,
unsigned polarity)
{
using namespace Fiasco;
using namespace Foc;
l4_umword_t mode;
@ -65,16 +66,17 @@ void Genode::Platform::setup_irq_mode(unsigned irq_number, unsigned trigger,
} else {
/*
* Translate ACPI interrupt mode (trigger/polarity) to Fiasco APIC
* Translate ACPI interrupt mode (trigger/polarity) to Fiasco.OC APIC
* values. Default is level low
*/
if (trigger == Irq_session::TRIGGER_LEVEL || trigger == Irq_session::TRIGGER_UNCHANGED) {
if (trigger == Irq_session::TRIGGER_LEVEL || trigger == Irq_session::TRIGGER_UNCHANGED) {
if (polarity == Irq_session::POLARITY_LOW || polarity == Irq_session::POLARITY_UNCHANGED)
mode = L4_IRQ_F_LEVEL_LOW;
else
mode = L4_IRQ_F_LEVEL_HIGH;
}
else {
} else {
if (polarity == Irq_session::POLARITY_LOW || polarity == Irq_session::POLARITY_UNCHANGED)
mode = L4_IRQ_F_NEG_EDGE;
else
@ -82,17 +84,14 @@ void Genode::Platform::setup_irq_mode(unsigned irq_number, unsigned trigger,
}
}
/*
* Set mode
*/
if (l4_error(l4_icu_set_mode(L4_BASE_ICU_CAP, irq_number, mode)))
error("setting mode for IRQ ", irq_number, " failed");
}
static bool cpu_name(char const * name) {
using Genode::uint32_t;
static bool cpu_name(char const * name)
{
uint32_t cpuid = 0, edx = 0, ebx = 0, ecx = 0;
asm volatile ("cpuid" : "+a" (cpuid), "=d" (edx), "=b"(ebx), "=c"(ecx));
return ebx == *reinterpret_cast<uint32_t const *>(name) &&
@ -100,15 +99,14 @@ static bool cpu_name(char const * name) {
ecx == *reinterpret_cast<uint32_t const *>(name + 8);
}
void Genode::Platform::_setup_platform_info(Xml_generator &xml,
Fiasco::l4_kernel_info_t &kip)
void Platform::_setup_platform_info(Xml_generator &xml,
Foc::l4_kernel_info_t &kip)
{
xml.node("features", [&] () {
/* XXX better detection required, best told us by kernel !? */
xml.attribute("svm", cpu_name("AuthenticAMD"));
xml.attribute("vmx", cpu_name("GenuineIntel"));
});
xml.attribute("vmx", cpu_name("GenuineIntel")); });
xml.node("tsc", [&] () {
xml.attribute("freq_khz" , kip.frequency_cpu);
});
xml.attribute("freq_khz" , kip.frequency_cpu); });
}

View File

@ -27,6 +27,7 @@ void Genode::platform_add_local_services(Rpc_entrypoint &ep,
{
static Vm_root vm_root(ep, heap, core_env().ram_allocator(),
core_env().local_rm(), trace_sources);
static Core_service<Vm_session_component> vm(services, vm_root);
static Io_port_root io_root(*core_env().pd_session(),

View File

@ -16,8 +16,10 @@
/* core includes */
#include <ipc_pager.h>
using namespace Genode;
void Genode::Ipc_pager::get_regs(Foc_thread_state &state) const
void Ipc_pager::get_regs(Foc_thread_state &state) const
{
state.ip = _regs.ip;
state.sp = _regs.sp;
@ -35,7 +37,7 @@ void Genode::Ipc_pager::get_regs(Foc_thread_state &state) const
}
void Genode::Ipc_pager::set_regs(Foc_thread_state const &state)
void Ipc_pager::set_regs(Foc_thread_state const &state)
{
_regs.ip = state.ip;
_regs.sp = state.sp;

View File

@ -16,8 +16,10 @@
/* core includes */
#include <ipc_pager.h>
using namespace Genode;
void Genode::Ipc_pager::get_regs(Foc_thread_state &state) const
void Ipc_pager::get_regs(Foc_thread_state &state) const
{
state.ip = _regs.ip;
state.sp = _regs.sp;
@ -42,7 +44,7 @@ void Genode::Ipc_pager::get_regs(Foc_thread_state &state) const
}
void Genode::Ipc_pager::set_regs(Foc_thread_state const &state)
void Ipc_pager::set_regs(Foc_thread_state const &state)
{
_regs.ip = state.ip;
_regs.sp = state.sp;

View File

@ -14,6 +14,9 @@
/* base-internal includes */
#include <base/internal/stack_area.h>
using namespace Genode;
/*
* The base address of the context area differs for core, because
* roottask on Fiasco.OC uses identity mappings. The virtual address range
@ -21,4 +24,4 @@
* address range that lies outside of the RAM of the currently supported
* platforms.
*/
Genode::addr_t Genode::stack_area_virtual_base() { return 0x20000000UL; }
addr_t Genode::stack_area_virtual_base() { return 0x20000000UL; }

View File

@ -24,12 +24,8 @@
#include <platform.h>
#include <core_env.h>
namespace Fiasco {
#include <l4/sys/debugger.h>
#include <l4/sys/factory.h>
#include <l4/sys/scheduler.h>
#include <l4/sys/thread.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
using namespace Genode;
@ -45,7 +41,7 @@ void Thread::_init_platform_thread(size_t, Type) { }
void Thread::start()
{
using namespace Fiasco;
using namespace Foc;
/* create and start platform thread */
Platform_thread &pt = *new (platform().core_mem_alloc())
@ -53,7 +49,7 @@ void Thread::start()
platform_specific().core_pd().bind_thread(pt);
l4_utcb_t *foc_utcb = (l4_utcb_t *)(pt.utcb());
l4_utcb_t * const foc_utcb = (l4_utcb_t *)(pt.utcb());
native_thread() = Native_thread(pt.gate().remote);
@ -84,7 +80,7 @@ void Thread::start()
uint64_t const sc_time = 0;
addr_t const kcap = (addr_t) platform_thread.pager_object_badge();
using namespace Fiasco;
using namespace Foc;
l4_kernel_clock_t ec_time = 0;
l4_msgtag_t res = l4_thread_stats_time(kcap, &ec_time);
if (l4_error(res))

View File

@ -20,10 +20,8 @@
#include <pd_session_component.h>
#include <cpu_thread_component.h>
namespace Fiasco {
#include <l4/sys/factory.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
using namespace Genode;
@ -45,7 +43,7 @@ Vm_session_component::Vm_session_component(Rpc_entrypoint &ep,
{
_cap_quota_guard().withdraw(Cap_quota{1});
using namespace Fiasco;
using namespace Foc;
l4_msgtag_t msg = l4_factory_create_vm(L4_BASE_FACTORY_CAP,
_task_vcpu.local.data()->kcap());
if (l4_error(msg)) {
@ -58,6 +56,7 @@ Vm_session_component::Vm_session_component(Rpc_entrypoint &ep,
_map.add_range(0UL - 0x1000, 0x1000);
}
Vm_session_component::~Vm_session_component()
{
for (;Vcpu * vcpu = _vcpus.first();) {
@ -92,7 +91,7 @@ Vcpu::Vcpu(Constrained_ram_allocator &ram_alloc,
throw;
}
Fiasco::l4_msgtag_t msg = l4_factory_create_irq(Fiasco::L4_BASE_FACTORY_CAP,
Foc::l4_msgtag_t msg = l4_factory_create_irq(Foc::L4_BASE_FACTORY_CAP,
_recall.local.data()->kcap());
if (l4_error(msg)) {
_ram_alloc.free(_ds_cap);
@ -122,18 +121,20 @@ Vm_session::Vcpu_id Vm_session_component::_create_vcpu(Thread_capability cap)
Vcpu * vcpu = nullptr;
try {
vcpu = new (_heap) Vcpu(_constrained_md_ram_alloc,
_cap_quota_guard(),
Vcpu_id {_id_alloc});
_cap_quota_guard(),
Vcpu_id {_id_alloc});
Fiasco::l4_cap_idx_t task = thread->platform_thread().setup_vcpu(_id_alloc, _task_vcpu, vcpu->recall_cap());
if (task == Fiasco::L4_INVALID_CAP)
Foc::l4_cap_idx_t task =
thread->platform_thread().setup_vcpu(_id_alloc, _task_vcpu, vcpu->recall_cap());
if (task == Foc::L4_INVALID_CAP)
throw 0;
_ep.apply(vcpu->ds_cap(), [&] (Dataspace_component *ds) {
if (!ds)
throw 1;
/* tell client where to find task cap */
*reinterpret_cast<Fiasco::l4_cap_idx_t *>(ds->phys_addr()) = task;
*reinterpret_cast<Foc::l4_cap_idx_t *>(ds->phys_addr()) = task;
});
} catch (int) {
if (vcpu)
@ -174,7 +175,7 @@ void Vm_session_component::_attach_vm_memory(Dataspace_component &dsc,
Flexpage_iterator flex(dsc.phys_addr() + attribute.offset, attribute.size,
guest_phys, attribute.size, guest_phys);
using namespace Fiasco;
using namespace Foc;
uint8_t flags = L4_FPAGE_RO;
if (dsc.writable() && attribute.writeable)
@ -207,7 +208,7 @@ void Vm_session_component::_detach_vm_memory(addr_t guest_phys, size_t size)
Flexpage page = flex.page();
while (page.valid()) {
using namespace Fiasco;
using namespace Foc;
l4_task_unmap(_task_vcpu.local.data()->kcap(),
l4_fpage(page.addr, page.log2_order, L4_FPAGE_RWX),

View File

@ -23,126 +23,127 @@
#include <base/internal/cap_map.h>
#include <base/internal/foc_assert.h>
namespace Genode {
namespace Genode { template <typename, unsigned> class Cap_index_allocator_tpl; }
/**
* Cap_index_allocator_tpl implements the Cap_index_allocator for Fiasco.OC.
*
* It's designed as a template because we need two distinguished versions
* for core and non-core processes with respect to dimensioning. Moreover,
* core needs more information within a Cap_index object, than the base
* class provides.
*
* \param T Cap_index specialization to use
* \param SZ size of Cap_index array used by the allocator
*/
template <typename T, unsigned SZ>
class Cap_index_allocator_tpl : public Cap_index_allocator
{
private:
/**
* Cap_index_allocator_tpl implements the Cap_index_allocator for Fiasco.OC.
*
* It's designed as a template because we need two distinguished versions
* for core and non-core processes with respect to dimensioning. Moreover,
* core needs more information within a Cap_index object, than the base
* class provides.
*
* \param T Cap_index specialization to use
* \param SZ size of Cap_index array used by the allocator
*/
template <typename T, unsigned SZ>
class Genode::Cap_index_allocator_tpl : public Cap_index_allocator
{
private:
/*
* Noncopyable
*/
Cap_index_allocator_tpl(Cap_index_allocator_tpl const &);
Cap_index_allocator_tpl &operator = (Cap_index_allocator_tpl const &);
Spin_lock _lock { }; /* used very early in initialization,
where normal lock isn't feasible */
enum {
/* everything below START_IDX is managed by core */
START_IDX = Foc::USER_BASE_CAP >> Foc::L4_CAP_SHIFT
};
protected:
unsigned char _data[SZ*sizeof(T)] { };
T * const _indices = reinterpret_cast<T*>(&_data);
public:
Cap_index_allocator_tpl() { }
/***********************************
** Cap_index_allocator interface **
***********************************/
Cap_index* alloc_range(size_t cnt) override
{
Lock_guard<Spin_lock> guard(_lock);
/*
* Noncopyable
* iterate through array and find unused, consecutive entries
*/
Cap_index_allocator_tpl(Cap_index_allocator_tpl const &);
Cap_index_allocator_tpl &operator = (Cap_index_allocator_tpl const &);
for (unsigned i = START_IDX, j = 0; (i+cnt) < SZ; i+=j+1, j=0) {
for (; j < cnt; j++)
if (_indices[i+j].used())
break;
Spin_lock _lock { }; /* used very early in initialization,
where normal lock isn't feasible */
enum {
/* everything below START_IDX is managed by core */
START_IDX = Fiasco::USER_BASE_CAP >> Fiasco::L4_CAP_SHIFT
};
protected:
unsigned char _data[SZ*sizeof(T)];
T* _indices;
public:
Cap_index_allocator_tpl() : _indices(reinterpret_cast<T*>(&_data)) {
memset(&_data, 0, sizeof(_data)); }
/***********************************
** Cap_index_allocator interface **
***********************************/
Cap_index* alloc_range(size_t cnt) override
{
Lock_guard<Spin_lock> guard(_lock);
/*
* iterate through array and find unused, consecutive entries
*/
for (unsigned i = START_IDX, j = 0; (i+cnt) < SZ; i+=j+1, j=0) {
for (; j < cnt; j++)
if (_indices[i+j].used())
break;
/* if we found a fitting hole, initialize the objects */
if (j == cnt) {
for (j = 0; j < cnt; j++)
new (&_indices[i+j]) T();
return &_indices[i];
}
/* if we found a fitting hole, initialize the objects */
if (j == cnt) {
for (j = 0; j < cnt; j++)
new (&_indices[i+j]) T();
return &_indices[i];
}
ASSERT(0, "cap index allocation failed");
return 0;
}
ASSERT(0, "cap index allocation failed");
return 0;
}
Cap_index* alloc(addr_t addr) override
{
Lock_guard<Spin_lock> guard(_lock);
/*
* construct the Cap_index pointer from the given
* address in capability space
*/
T * const obj = reinterpret_cast<T*>(kcap_to_idx(addr));
if (obj < &_indices[0] || obj >= &_indices[SZ]) {
ASSERT(0, "cap index out of bounds");
throw Index_out_of_bounds();
}
Cap_index* alloc(addr_t addr) override
{
Lock_guard<Spin_lock> guard(_lock);
return new (obj) T();
}
/*
* construct the Cap_index pointer from the given
* address in capability space
*/
T* obj = reinterpret_cast<T*>(kcap_to_idx(addr));
void free(Cap_index* idx, size_t cnt) override
{
Lock_guard<Spin_lock> guard(_lock);
T *obj = static_cast<T*>(idx);
for (size_t i = 0; i < cnt; obj++, i++) {
/* range check given pointer address */
if (obj < &_indices[0] || obj >= &_indices[SZ]) {
ASSERT(0, "cap index out of bounds");
throw Index_out_of_bounds();
}
return new (obj) T();
delete obj;
}
}
void free(Cap_index* idx, size_t cnt) override
{
Lock_guard<Spin_lock> guard(_lock);
addr_t idx_to_kcap(Cap_index const *idx) const override
{
return ((T const *)idx - &_indices[0]) << Foc::L4_CAP_SHIFT;
}
T* obj = static_cast<T*>(idx);
for (size_t i = 0; i < cnt; obj++, i++) {
/* range check given pointer address */
if (obj < &_indices[0] || obj >= &_indices[SZ]) {
ASSERT(0, "cap index out of bounds");
throw Index_out_of_bounds();
}
delete obj;
}
}
Cap_index *kcap_to_idx(addr_t kcap) override {
return &_indices[kcap >> Foc::L4_CAP_SHIFT]; }
addr_t idx_to_kcap(Cap_index const *idx) const override {
return ((T const *)idx - &_indices[0]) << Fiasco::L4_CAP_SHIFT;
}
bool static_idx(Cap_index *idx) override {
return ((T*)idx) < &_indices[START_IDX]; }
Cap_index* kcap_to_idx(addr_t kcap) override {
return &_indices[kcap >> Fiasco::L4_CAP_SHIFT]; }
void reinit() override
{
construct_at<Cap_index_allocator_tpl<T, SZ> >(this);
}
bool static_idx(Cap_index *idx) override {
return ((T*)idx) < &_indices[START_IDX]; }
void reinit() override
{
construct_at<Cap_index_allocator_tpl<T, SZ> >(this);
}
size_t max_caps() const override { return SZ; }
};
}
size_t max_caps() const override { return SZ; }
};
#endif /* _INCLUDE__BASE__CAP_ALLOC_H_ */

View File

@ -42,205 +42,15 @@ namespace Genode {
typedef Native_capability::Data Cap_index;
/**
* Allocator for Cap_index objects.
*
* This is just an interface, as the real allocator has to be
* implemented platform-specific.
*/
class Cap_index_allocator: Noncopyable
{
public:
class Index_out_of_bounds : public Exception { };
class Region_conflict : public Exception { };
virtual ~Cap_index_allocator() {}
/**
* Allocate a range of Cap_index objects
*
* \param cnt number of objects to allocate
* \return pointer to first allocated object, or zero if
* out of entries
*/
virtual Cap_index* alloc_range(size_t cnt) = 0;
/**
* Allocate a Cap_index object at a specific
* point in the capability space
*
* \param kcap address in capability space
* \throw Index_out_of_bounds if address is out of scope
* \return pointer to allocated object
*/
virtual Cap_index* alloc(addr_t kcap) = 0;
/**
* Free a range of Cap_index objects
*
* \param idx pointer to first object in range
* \param cnt number of objects to free
* \throw Index_out_of_bounds if address is out of scope
*/
virtual void free(Cap_index *idx, size_t cnt) = 0;
/**
* Get the Cap_index object's address in capability space
*
* \param idx pointer to the Cap_index object in question
*/
virtual addr_t idx_to_kcap(Cap_index const *idx) const = 0;
/**
* Get the Cap_index object of a specific location
* in the capability space
*
* \param kcap the address in the capability space
*/
virtual Cap_index* kcap_to_idx(addr_t kcap) = 0;
/**
* Returns whether a Cap_index object is from the region
* controlled by core, or not.
*
* \param idx pointer to the Cap_index object in question
*/
virtual bool static_idx(Cap_index *idx) = 0;
/**
* Redo construction of the object
*/
virtual void reinit() = 0;
/**
* Return capacity of allocator
*/
virtual size_t max_caps() const = 0;
};
class Cap_index_allocator;
/**
* Get the global Cap_index_allocator of the process.
*/
Cap_index_allocator &cap_idx_alloc();
/**
* Low-level spin-lock to protect Cap_index_allocator and the Cap_map
*
* We cannot use a normal Genode lock because this lock is used by code
* executed prior the initialization of Genode
*/
class Spin_lock
{
private:
volatile int _spinlock;
public:
/**
* Constructor
*/
Spin_lock();
void lock();
void unlock();
/**
* Lock guard
*/
typedef Genode::Lock_guard<Spin_lock> Guard;
};
class Native_capability;
/**
* The Capability_map is an AVL-tree of Cap_index objects that can be
* found via the global capability id
*
* It is used to re-find capabilities whenever a capability gets
* transfered to a process, so that we can re-use an existing one
* to save entries in the capability space, and prevent leaks of
* them.
*/
class Capability_map
:
private Noncopyable
{
private:
Avl_tree<Cap_index> _tree { };
Spin_lock _lock { };
public:
/**
* Find an existing Cap_index via a capability id
*
* \param id the global capability id
* \return pointer of Cap_index when found, otherwise zero
*/
Cap_index* find(int id);
/**
* Create and insert a new Cap_index with a specific capability id
*
* Allocation of the Cap_index is done via the global
* Cap_index_allocator, which might throw exceptions that aren't
* caught by this method
*
* \param id the global capability id
* \return pointer to the new Cap_index object, or zero
* when allocation failed
*/
Cap_index* insert(int id);
/**
* Create and insert a new Cap_index with a specific capability id,
* and location in capability space
*
* A previously existent entry with the same id gets removed!
*
* \param id the global capability id
* \param kcap address in capability space
* \return pointer to the new Cap_index object, or zero
* when allocation failed
*/
Cap_index* insert(int id, addr_t kcap);
/**
* Create and insert a new Cap_index with a specific capability id
* and map from given kcap to newly allocated one,
* if the an entry with the same id exists already,
* it is returned if it points to the same kernel-object,
* or gets overridden if it's already invalid.
*
* Allocation of the Cap_index is done via the global
* Cap_index_allocator, which might throw exceptions that aren't
* caught by this method
*
* \param id the global capability id
* \return pointer to the new Cap_index object, or zero
* when allocation failed, or when a valid entry
* with the same id exists and it's kernel-object
* differs to the one given by kcap
*/
Cap_index* insert_map(int id, addr_t kcap);
/**
* Remove (resp. invalidate) a Cap_index object
*
* \param i pointer to Cap_index object to remove
*/
void remove(Cap_index* i);
};
class Spin_lock;
class Capability_map;
/**
* Get the global Capability_map of the process.
@ -248,4 +58,192 @@ namespace Genode {
Capability_map &cap_map();
}
/**
* Allocator for Cap_index objects.
*
* This is just an interface, as the real allocator has to be
* implemented platform-specific.
*/
class Genode::Cap_index_allocator: Noncopyable
{
public:
class Index_out_of_bounds : public Exception { };
class Region_conflict : public Exception { };
virtual ~Cap_index_allocator() {}
/**
* Allocate a range of Cap_index objects
*
* \param cnt number of objects to allocate
* \return pointer to first allocated object, or zero if
* out of entries
*/
virtual Cap_index* alloc_range(size_t cnt) = 0;
/**
* Allocate a Cap_index object at a specific
* point in the capability space
*
* \param kcap address in capability space
* \throw Index_out_of_bounds if address is out of scope
* \return pointer to allocated object
*/
virtual Cap_index* alloc(addr_t kcap) = 0;
/**
* Free a range of Cap_index objects
*
* \param idx pointer to first object in range
* \param cnt number of objects to free
* \throw Index_out_of_bounds if address is out of scope
*/
virtual void free(Cap_index *idx, size_t cnt) = 0;
/**
* Get the Cap_index object's address in capability space
*
* \param idx pointer to the Cap_index object in question
*/
virtual addr_t idx_to_kcap(Cap_index const *idx) const = 0;
/**
* Get the Cap_index object of a specific location
* in the capability space
*
* \param kcap the address in the capability space
*/
virtual Cap_index* kcap_to_idx(addr_t kcap) = 0;
/**
* Returns whether a Cap_index object is from the region
* controlled by core, or not.
*
* \param idx pointer to the Cap_index object in question
*/
virtual bool static_idx(Cap_index *idx) = 0;
/**
* Redo construction of the object
*/
virtual void reinit() = 0;
/**
* Return capacity of allocator
*/
virtual size_t max_caps() const = 0;
};
/**
* Low-level spin-lock to protect Cap_index_allocator and the Cap_map
*
* We cannot use a normal Genode lock because this lock is used by code
* executed prior the initialization of Genode
*/
class Genode::Spin_lock
{
private:
volatile int _spinlock;
public:
/**
* Constructor
*/
Spin_lock();
void lock();
void unlock();
/**
* Lock guard
*/
typedef Genode::Lock_guard<Spin_lock> Guard;
};
/**
* The Capability_map is an AVL-tree of Cap_index objects that can be
* found via the global capability id
*
* It is used to re-find capabilities whenever a capability gets
* transfered to a process, so that we can re-use an existing one
* to save entries in the capability space, and prevent leaks of
* them.
*/
class Genode::Capability_map : private Noncopyable
{
private:
Avl_tree<Cap_index> _tree { };
Spin_lock _lock { };
public:
/**
* Find an existing Cap_index via a capability id
*
* \param id the global capability id
* \return pointer of Cap_index when found, otherwise zero
*/
Cap_index* find(int id);
/**
* Create and insert a new Cap_index with a specific capability id
*
* Allocation of the Cap_index is done via the global
* Cap_index_allocator, which might throw exceptions that aren't
* caught by this method
*
* \param id the global capability id
* \return pointer to the new Cap_index object, or zero
* when allocation failed
*/
Cap_index* insert(int id);
/**
* Create and insert a new Cap_index with a specific capability id,
* and location in capability space
*
* A previously existent entry with the same id gets removed!
*
* \param id the global capability id
* \param kcap address in capability space
* \return pointer to the new Cap_index object, or zero
* when allocation failed
*/
Cap_index* insert(int id, addr_t kcap);
/**
* Create and insert a new Cap_index with a specific capability id
* and map from given kcap to newly allocated one,
* if the an entry with the same id exists already,
* it is returned if it points to the same kernel-object,
* or gets overridden if it's already invalid.
*
* Allocation of the Cap_index is done via the global
* Cap_index_allocator, which might throw exceptions that aren't
* caught by this method
*
* \param id the global capability id
* \return pointer to the new Cap_index object, or zero
* when allocation failed, or when a valid entry
* with the same id exists and it's kernel-object
* differs to the one given by kcap
*/
Cap_index *insert_map(int id, addr_t kcap);
/**
* Remove (resp. invalidate) a Cap_index object
*
* \param i pointer to Cap_index object to remove
*/
void remove(Cap_index *);
};
#endif /* _INCLUDE__BASE__CAP_MAP_H_ */

View File

@ -17,14 +17,13 @@
/* Genode includes */
#include <base/log.h>
namespace Fiasco {
#include <l4/sys/kdebug.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
#define ASSERT(e, s) \
do { if (!(e)) { \
Genode::raw("assertion failed: ", s, " at ", __FILE__, ":", __LINE__); \
Fiasco::enter_kdebug("ASSERT"); \
Foc::enter_kdebug("ASSERT"); \
} \
} while(0)

View File

@ -26,16 +26,13 @@
#include <base/internal/native_thread.h>
/* Fiasco.OC includes */
namespace Fiasco {
#include <l4/sys/irq.h>
#include <l4/sys/thread.h>
}
#include <foc/syscall.h>
/**
* Yield CPU time
*/
static inline void thread_yield() { Fiasco::l4_thread_yield(); }
static inline void thread_yield() { Foc::l4_thread_yield(); }
/**
@ -49,11 +46,11 @@ static inline void thread_yield() { Fiasco::l4_thread_yield(); }
*/
static inline bool thread_check_stopped_and_restart(Genode::Thread *thread_base)
{
Fiasco::l4_cap_idx_t tid = thread_base ?
Foc::l4_cap_idx_t tid = thread_base ?
thread_base->native_thread().kcap :
Fiasco::MAIN_THREAD_CAP;
Fiasco::l4_cap_idx_t irq = tid + Fiasco::THREAD_IRQ_CAP;
Fiasco::l4_irq_trigger(irq);
Foc::MAIN_THREAD_CAP;
Foc::l4_cap_idx_t irq = tid + Foc::THREAD_IRQ_CAP;
Foc::l4_irq_trigger(irq);
return true;
}
@ -63,10 +60,10 @@ static inline bool thread_check_stopped_and_restart(Genode::Thread *thread_base)
*/
static inline void thread_switch_to(Genode::Thread *thread_base)
{
Fiasco::l4_cap_idx_t tid = thread_base ?
Foc::l4_cap_idx_t tid = thread_base ?
thread_base->native_thread().kcap :
Fiasco::MAIN_THREAD_CAP;
Fiasco::l4_thread_switch(tid);
Foc::MAIN_THREAD_CAP;
Foc::l4_thread_switch(tid);
}
@ -80,13 +77,13 @@ __attribute__((noinline))
__attribute__((used))
static void thread_stop_myself(Genode::Thread *)
{
using namespace Fiasco;
using namespace Foc;
Genode::Thread *myself = Genode::Thread::myself();
Fiasco::l4_cap_idx_t tid = myself ?
Foc::l4_cap_idx_t tid = myself ?
myself->native_thread().kcap :
Fiasco::MAIN_THREAD_CAP;
Fiasco::l4_cap_idx_t irq = tid + THREAD_IRQ_CAP;
Foc::MAIN_THREAD_CAP;
Foc::l4_cap_idx_t irq = tid + THREAD_IRQ_CAP;
l4_irq_receive(irq, L4_IPC_NEVER);
}

View File

@ -18,8 +18,9 @@
#ifndef _INCLUDE__BASE__INTERNAL__NATIVE_UTCB_H_
#define _INCLUDE__BASE__INTERNAL__NATIVE_UTCB_H_
namespace Fiasco {
#include <l4/sys/utcb.h>
#include <foc/syscall.h>
namespace Foc {
enum Utcb_regs {
UTCB_TCR_BADGE = 1,
@ -27,11 +28,13 @@ namespace Fiasco {
};
}
namespace Genode { struct Native_utcb; }
struct Genode::Native_utcb
{
Fiasco::l4_utcb_t *foc_utcb = nullptr;
Foc::l4_utcb_t *foc_utcb = nullptr;
};
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_UTCB_H_ */

View File

@ -26,21 +26,20 @@
#include <base/internal/crt0.h>
#include <base/internal/cap_map.h>
namespace Genode {
static inline Parent_capability parent_cap()
{
unsigned long const local_name = _parent_cap;
static Cap_index *i = cap_map().insert(local_name, Fiasco::PARENT_CAP);
static Cap_index *i = cap_map().insert(local_name, Foc::PARENT_CAP);
/*
* Update local name after a parent capability got reloaded via
* 'Platform_env::reload_parent_cap()'.
*/
if (i->id() != local_name) {
cap_map().remove(i);
i = cap_map().insert(local_name, Fiasco::PARENT_CAP);
i = cap_map().insert(local_name, Foc::PARENT_CAP);
}
return reinterpret_cap_cast<Parent>(Native_capability(i));

View File

@ -20,7 +20,7 @@
namespace Genode {
void raw_write_string(char const *str) {
Fiasco::outstring(const_cast<char *>(str)); }
Foc::outstring(const_cast<char *>(str)); }
}
#endif /* _INCLUDE__BASE__INTERNAL__RAW_WRITE_STRING_H_ */

View File

@ -11,13 +11,13 @@
* under the terms of the GNU Affero General Public License version 3.
*/
namespace Fiasco {
#include <l4/sys/cache.h>
}
#include <cpu/cache.h>
#include <foc/syscall.h>
void Genode::cache_coherent(Genode::addr_t addr, Genode::size_t size)
using namespace Genode;
void Genode::cache_coherent(addr_t addr, size_t size)
{
Fiasco::l4_cache_coherent(addr, addr + size);
Foc::l4_cache_coherent(addr, addr + size);
}

View File

@ -13,8 +13,11 @@
#include <base/internal/cap_alloc.h>
Genode::Cap_index_allocator &Genode::cap_idx_alloc()
using namespace Genode;
Cap_index_allocator &Genode::cap_idx_alloc()
{
static Genode::Cap_index_allocator_tpl<Cap_index,4096> alloc;
static Cap_index_allocator_tpl<Cap_index,4096> alloc;
return alloc;
}

View File

@ -29,14 +29,11 @@
* our expectations below macro can be used.
*/
#ifdef TEST_KERN_CAP_EQUAL
namespace Fiasco {
#include <l4/sys/debugger.h>
}
inline bool CHECK_CAP_EQUAL(bool equal, Genode::addr_t cap1,
Genode::addr_t cap2)
{
unsigned long id1 = Fiasco::l4_debugger_global_id(cap1),
id2 = Fiasco::l4_debugger_global_id(cap2);
unsigned long id1 = Foc::l4_debugger_global_id(cap1),
id2 = Foc::l4_debugger_global_id(cap2);
ASSERT(((id1 == id2) == equal), "CAPS NOT EQUAL!!!");
return equal;
}
@ -49,6 +46,9 @@ inline bool CHECK_CAP_EQUAL(bool equal, Genode::addr_t,
#endif /* TEST_KERN_CAP_EQUAL */
using namespace Genode;
/***********************
** Cap_index class **
***********************/
@ -56,13 +56,11 @@ inline bool CHECK_CAP_EQUAL(bool equal, Genode::addr_t,
static volatile int _cap_index_spinlock = SPINLOCK_UNLOCKED;
bool Genode::Cap_index::higher(Genode::Cap_index *n) { return n->_id > _id; }
bool Cap_index::higher(Cap_index *n) { return n->_id > _id; }
Genode::Cap_index* Genode::Cap_index::find_by_id(Genode::uint16_t id)
Cap_index* Cap_index::find_by_id(uint16_t id)
{
using namespace Genode;
if (_id == id) return this;
Cap_index *n = Avl_node<Cap_index>::child(id > _id);
@ -70,31 +68,33 @@ Genode::Cap_index* Genode::Cap_index::find_by_id(Genode::uint16_t id)
}
Genode::addr_t Genode::Cap_index::kcap() const {
return cap_idx_alloc().idx_to_kcap(this); }
addr_t Cap_index::kcap() const
{
return cap_idx_alloc().idx_to_kcap(this);
}
Genode::uint8_t Genode::Cap_index::inc()
uint8_t Cap_index::inc()
{
/* con't ref-count index that are controlled by core */
if (cap_idx_alloc().static_idx(this))
return 1;
spinlock_lock(&_cap_index_spinlock);
Genode::uint8_t ret = ++_ref_cnt;
uint8_t ret = ++_ref_cnt;
spinlock_unlock(&_cap_index_spinlock);
return ret;
}
Genode::uint8_t Genode::Cap_index::dec()
uint8_t Cap_index::dec()
{
/* con't ref-count index that are controlled by core */
if (cap_idx_alloc().static_idx(this))
return 1;
spinlock_lock(&_cap_index_spinlock);
Genode::uint8_t ret = --_ref_cnt;
uint8_t ret = --_ref_cnt;
spinlock_unlock(&_cap_index_spinlock);
return ret;
}
@ -104,18 +104,16 @@ Genode::uint8_t Genode::Cap_index::dec()
** Capability_map class **
****************************/
Genode::Cap_index* Genode::Capability_map::find(int id)
Cap_index* Capability_map::find(int id)
{
Genode::Lock_guard<Spin_lock> guard(_lock);
Lock_guard<Spin_lock> guard(_lock);
return _tree.first() ? _tree.first()->find_by_id(id) : 0;
}
Genode::Cap_index* Genode::Capability_map::insert(int id)
Cap_index* Capability_map::insert(int id)
{
using namespace Genode;
Lock_guard<Spin_lock> guard(_lock);
ASSERT(!_tree.first() || !_tree.first()->find_by_id(id),
@ -130,10 +128,8 @@ Genode::Cap_index* Genode::Capability_map::insert(int id)
}
Genode::Cap_index* Genode::Capability_map::insert(int id, addr_t kcap)
Cap_index* Capability_map::insert(int id, addr_t kcap)
{
using namespace Genode;
Lock_guard<Spin_lock> guard(_lock);
/* remove potentially existent entry */
@ -150,10 +146,9 @@ Genode::Cap_index* Genode::Capability_map::insert(int id, addr_t kcap)
}
Genode::Cap_index* Genode::Capability_map::insert_map(int id, addr_t kcap)
Cap_index* Capability_map::insert_map(int id, addr_t kcap)
{
using namespace Genode;
using namespace Fiasco;
using namespace Foc;
Lock_guard<Spin_lock> guard(_lock);
@ -196,9 +191,9 @@ Genode::Cap_index* Genode::Capability_map::insert_map(int id, addr_t kcap)
}
Genode::Capability_map &Genode::cap_map()
Capability_map &Genode::cap_map()
{
static Genode::Capability_map map;
static Capability_map map;
return map;
}
@ -207,22 +202,23 @@ Genode::Capability_map &Genode::cap_map()
** Capability_space **
**********************/
Fiasco::l4_cap_idx_t Genode::Capability_space::alloc_kcap()
Foc::l4_cap_idx_t Capability_space::alloc_kcap()
{
return cap_idx_alloc().alloc_range(1)->kcap();
}
void Genode::Capability_space::free_kcap(Fiasco::l4_cap_idx_t kcap)
void Capability_space::free_kcap(Foc::l4_cap_idx_t kcap)
{
Genode::Cap_index *idx = Genode::cap_idx_alloc().kcap_to_idx(kcap);
Genode::cap_idx_alloc().free(idx, 1);
Cap_index *idx = cap_idx_alloc().kcap_to_idx(kcap);
cap_idx_alloc().free(idx, 1);
}
Fiasco::l4_cap_idx_t Genode::Capability_space::kcap(Native_capability cap)
Foc::l4_cap_idx_t Capability_space::kcap(Native_capability cap)
{
if (cap.data() == nullptr)
Genode::raw("Native_capability data is NULL!");
raw("Native_capability data is NULL!");
return cap.data()->kcap();
}

View File

@ -15,10 +15,11 @@
#include <base/internal/cap_map.h>
void Genode::Capability_map::remove(Genode::Cap_index* i)
{
using namespace Genode;
using namespace Genode;
void Capability_map::remove(Genode::Cap_index* i)
{
Lock_guard<Spin_lock> guard(_lock);
if (i) {

View File

@ -11,10 +11,8 @@
* under the terms of the GNU Affero General Public License version 3.
*/
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/types.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
/* base-internal includes */
#include <base/internal/cap_map.h>

View File

@ -20,7 +20,6 @@
* --------------------------------------------------------------
*/
/* Genode includes */
#include <base/blocking.h>
#include <base/ipc.h>
@ -35,15 +34,10 @@
#include <base/internal/foc_assert.h>
/* Fiasco.OC includes */
namespace Fiasco {
#include <l4/sys/consts.h>
#include <l4/sys/ipc.h>
#include <l4/sys/types.h>
#include <l4/sys/utcb.h>
}
#include <foc/syscall.h>
using namespace Genode;
using namespace Fiasco;
using namespace Foc;
/***************
@ -55,7 +49,7 @@ enum Debug { DEBUG_MSG = 1 };
static inline bool ipc_error(l4_msgtag_t tag, bool print)
{
int ipc_error = l4_ipc_error(tag, l4_utcb());
int const ipc_error = l4_ipc_error(tag, l4_utcb());
if (ipc_error && print) raw("Ipc error: ", ipc_error, " occurred!");
return ipc_error;
}
@ -305,8 +299,7 @@ static bool badge_matches_label(unsigned long badge, unsigned long label)
}
void Genode::ipc_reply(Native_capability, Rpc_exception_code exc,
Msgbuf_base &snd_msg)
void Genode::ipc_reply(Native_capability, Rpc_exception_code exc, Msgbuf_base &snd_msg)
{
l4_msgtag_t tag = copy_msgbuf_to_utcb(snd_msg, exc.value);
@ -316,10 +309,10 @@ void Genode::ipc_reply(Native_capability, Rpc_exception_code exc,
}
Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &,
Rpc_exception_code exc,
Msgbuf_base &reply_msg,
Msgbuf_base &request_msg)
Rpc_request Genode::ipc_reply_wait(Reply_capability const &,
Rpc_exception_code exc,
Msgbuf_base &reply_msg,
Msgbuf_base &request_msg)
{
Receive_window &rcv_window = Thread::myself()->native_thread().rcv_window;
@ -372,7 +365,7 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &,
Ipc_server::Ipc_server()
:
Native_capability((Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE])
Native_capability((Cap_index*)Foc::l4_utcb_tcr()->user[Foc::UTCB_TCR_BADGE])
{
Thread::myself()->native_thread().rcv_window.init();
}
@ -406,6 +399,6 @@ addr_t Receive_window::rcv_cap_sel_base()
addr_t Receive_window::rcv_cap_sel(unsigned i)
{
return rcv_cap_sel_base() + i*Fiasco::L4_CAP_SIZE;
return rcv_cap_sel_base() + i*Foc::L4_CAP_SIZE;
}

View File

@ -23,12 +23,9 @@
#include <base/internal/capability_data.h>
#include <base/internal/native_thread.h>
/* Fiasco includes */
/* Fiasco.OC includes */
#include <foc_native_cpu/client.h>
namespace Fiasco {
#include <l4/sys/irq.h>
}
#include <foc/syscall.h>
using namespace Genode;
@ -40,7 +37,7 @@ Signal_source_client::Signal_source_client(Capability<Signal_source> cap)
/* request mapping of semaphore capability selector */
_sem(call<Rpc_request_semaphore>())
{
using namespace Fiasco;
using namespace Foc;
Foc_native_cpu_client cpu_client(env_deprecated()->cpu_session()->native_cpu());
Native_capability thread_cap = cpu_client.native_cap(Thread::myself()->cap());
@ -52,7 +49,7 @@ Signal_source_client::Signal_source_client(Capability<Signal_source> cap)
Signal_source_client::~Signal_source_client()
{
Fiasco::l4_irq_detach(_sem.data()->kcap());
Foc::l4_irq_detach(_sem.data()->kcap());
}
@ -60,7 +57,7 @@ __attribute__((optimize("-fno-omit-frame-pointer")))
__attribute__((noinline))
Signal_source_client::Signal Signal_source_client::wait_for_signal()
{
using namespace Fiasco;
using namespace Foc;
Signal signal;
do {

View File

@ -17,11 +17,13 @@
#include <base/internal/cap_map.h>
#include <base/internal/spin_lock.h>
Genode::Spin_lock::Spin_lock() : _spinlock(SPINLOCK_UNLOCKED) {}
using namespace Genode;
void Genode::Spin_lock::lock() { spinlock_lock(&_spinlock); }
Spin_lock::Spin_lock() : _spinlock(SPINLOCK_UNLOCKED) {}
void Genode::Spin_lock::unlock() { spinlock_unlock(&_spinlock); }
void Spin_lock::lock() { spinlock_lock(&_spinlock); }
void Spin_lock::unlock() { spinlock_unlock(&_spinlock); }

View File

@ -22,6 +22,8 @@
#include <base/internal/native_utcb.h>
#include <base/internal/cap_map.h>
using namespace Genode;
/*****************************
** Startup library support **
@ -29,17 +31,15 @@
void prepare_init_main_thread()
{
using namespace Genode;
enum { THREAD_CAP_ID = 1 };
Cap_index * ci(cap_map().insert(THREAD_CAP_ID, Fiasco::MAIN_THREAD_CAP));
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE] = (unsigned long)ci;
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_THREAD_OBJ] = 0;
Cap_index * ci(cap_map().insert(THREAD_CAP_ID, Foc::MAIN_THREAD_CAP));
Foc::l4_utcb_tcr()->user[Foc::UTCB_TCR_BADGE] = (unsigned long)ci;
Foc::l4_utcb_tcr()->user[Foc::UTCB_TCR_THREAD_OBJ] = 0;
}
void prepare_reinit_main_thread()
{
using namespace Genode;
construct_at<Capability_map>(&cap_map());
cap_idx_alloc().reinit();
prepare_init_main_thread();
@ -50,13 +50,11 @@ void prepare_reinit_main_thread()
** Thread **
************/
void Genode::Thread::_thread_bootstrap() { }
void Thread::_thread_bootstrap() { }
void Genode::Thread::_thread_start()
void Thread::_thread_start()
{
using namespace Genode;
Thread::myself()->_thread_bootstrap();
Thread::myself()->entry();
Thread::myself()->_join.wakeup();

View File

@ -17,10 +17,12 @@
/* base-internal includes */
#include <base/internal/native_utcb.h>
using namespace Genode;
Genode::Thread *Genode::Thread::myself()
Thread *Thread::myself()
{
using namespace Fiasco;
using namespace Foc;
return reinterpret_cast<Thread*>(l4_utcb_tcr()->user[UTCB_TCR_THREAD_OBJ]);
}

View File

@ -1,5 +1,5 @@
/*
* \brief Fiasco-specific implementation of the non-core startup Thread API
* \brief Fiasco.OC-specific implementation of the non-core startup Thread API
* \author Norman Feske
* \author Stefan Kalkowski
* \author Martin Stein
@ -27,17 +27,15 @@
#include <base/internal/cap_map.h>
#include <base/internal/globals.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/utcb.h>
}
/* Fiasco.OC includes */
#include <foc/syscall.h>
using namespace Genode;
void Thread::_deinit_platform_thread()
{
using namespace Fiasco;
using namespace Foc;
if (native_thread().kcap && _thread_cap.valid()) {
Cap_index *i = (Cap_index*)l4_utcb_tcr_u(utcb()->foc_utcb)->user[UTCB_TCR_BADGE];
@ -51,8 +49,8 @@ void Thread::_init_platform_thread(size_t weight, Type type)
{
_init_cpu_session_and_trace_control();
if (type == NORMAL)
{
if (type == NORMAL) {
/* create thread at core */
_thread_cap = _cpu_session->create_thread(env_deprecated()->pd_session_cap(),
name(), _affinity,
@ -64,22 +62,23 @@ void Thread::_init_platform_thread(size_t weight, Type type)
return;
}
/* adjust values whose computation differs for a main thread */
native_thread().kcap = Fiasco::MAIN_THREAD_CAP;
native_thread().kcap = Foc::MAIN_THREAD_CAP;
_thread_cap = main_thread_cap();
if (!_thread_cap.valid())
throw Cpu_session::Thread_creation_failed();
/* make thread object known to the Fiasco environment */
/* make thread object known to the Fiasco.OC environment */
addr_t const t = (addr_t)this;
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_THREAD_OBJ] = t;
Foc::l4_utcb_tcr()->user[Foc::UTCB_TCR_THREAD_OBJ] = t;
}
void Thread::start()
{
using namespace Fiasco;
using namespace Foc;
Foc_native_cpu_client native_cpu(_cpu_session->native_cpu());
@ -89,7 +88,7 @@ void Thread::start()
catch (...) { throw Cpu_session::Thread_creation_failed(); }
/* remember UTCB of the new thread */
Fiasco::l4_utcb_t * const foc_utcb = (Fiasco::l4_utcb_t *)state.utcb;
Foc::l4_utcb_t * const foc_utcb = (Foc::l4_utcb_t *)state.utcb;
utcb()->foc_utcb = foc_utcb;
native_thread() = Native_thread(state.kcap);

View File

@ -11,32 +11,31 @@
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <base/allocator.h>
#include <base/attached_rom_dataspace.h>
#include <base/env.h>
#include <base/registry.h>
#include <vm_session/client.h>
#include <cpu/vm_state.h>
#include <trace/timestamp.h>
namespace Fiasco {
#include <l4/sys/consts.h>
#include <l4/sys/irq.h>
#include <l4/sys/thread.h>
#include <l4/sys/types.h>
/* Fiasco.OC includes */
#include <foc/syscall.h>
#include <foc/native_thread.h>
#include <foc/native_capability.h>
namespace Foc {
#include <l4/sys/vcpu.h>
#include <l4/sys/__vm-svm.h>
#include <l4/sys/__vm-vmx.h>
}
#include <foc/native_thread.h>
#include <foc/native_capability.h>
using namespace Genode;
enum Virt { VMX, SVM, UNKNOWN };
using namespace Genode;
static uint32_t svm_features()
{
@ -45,13 +44,17 @@ static uint32_t svm_features()
return edx;
}
static bool svm_np() { return svm_features() & (1U << 0); }
struct Vcpu;
static Genode::Registry<Genode::Registered<Vcpu> > vcpus;
struct Vcpu : Genode::Thread
static Registry<Registered<Vcpu> > vcpus;
struct Vcpu : Thread
{
private:
@ -82,40 +85,40 @@ struct Vcpu : Genode::Thread
CS_AR = 0x4816,
CS_BASE = 0x6808,
SS_SEL = 0x0804,
SS_LIMIT = 0x4804,
SS_AR = 0x4818,
SS_BASE = 0x680a,
SS_SEL = 0x0804,
SS_LIMIT = 0x4804,
SS_AR = 0x4818,
SS_BASE = 0x680a,
ES_SEL = 0x0800,
ES_LIMIT = 0x4800,
ES_AR = 0x4814,
ES_BASE = 0x6806,
ES_SEL = 0x0800,
ES_LIMIT = 0x4800,
ES_AR = 0x4814,
ES_BASE = 0x6806,
DS_SEL = 0x0806,
DS_LIMIT = 0x4806,
DS_AR = 0x481a,
DS_BASE = 0x680c,
DS_SEL = 0x0806,
DS_LIMIT = 0x4806,
DS_AR = 0x481a,
DS_BASE = 0x680c,
FS_SEL = 0x0808,
FS_LIMIT = 0x4808,
FS_AR = 0x481c,
FS_BASE = 0x680e,
FS_SEL = 0x0808,
FS_LIMIT = 0x4808,
FS_AR = 0x481c,
FS_BASE = 0x680e,
GS_SEL = 0x080a,
GS_LIMIT = 0x480a,
GS_AR = 0x481e,
GS_BASE = 0x6810,
GS_SEL = 0x080a,
GS_LIMIT = 0x480a,
GS_AR = 0x481e,
GS_BASE = 0x6810,
LDTR_SEL = 0x080c,
LDTR_LIMIT = 0x480c,
LDTR_AR = 0x4820,
LDTR_BASE = 0x6812,
TR_SEL = 0x080e,
TR_LIMIT = 0x480e,
TR_AR = 0x4822,
TR_BASE = 0x6814,
TR_SEL = 0x080e,
TR_LIMIT = 0x480e,
TR_AR = 0x4822,
TR_BASE = 0x6814,
IDTR_LIMIT = 0x4812,
IDTR_BASE = 0x6818,
@ -135,12 +138,13 @@ struct Vcpu : Genode::Thread
INTR_INFO = 0x4016,
INTR_ERROR = 0x4018,
ENTRY_INST_LEN = 0x401a,
IDT_INFO = 0x4408,
IDT_ERROR = 0x440a,
IDT_INFO = 0x4408,
IDT_ERROR = 0x440a,
EXIT_CTRL = 0x400c,
EXIT_CTRL = 0x400c,
ENTRY_CTRL = 0x4012,
TSC_OFF_LO = 0x2010,
@ -149,22 +153,24 @@ struct Vcpu : Genode::Thread
MSR_FMASK = 0x2842,
MSR_LSTAR = 0x2844,
MSR_STAR = 0x284a,
KERNEL_GS_BASE = 0x284c,
CR4_VMX = 1 << 13,
CR4_VMX = 1 << 13,
INTEL_EXIT_INVALID = 0x21,
};
enum Vmcb
{
CTRL0_VINTR = 1u << 4,
CTRL0_IO = 1u << 27,
CTRL0_MSR = 1u << 28,
CTRL0_VINTR = 1u << 4,
CTRL0_IO = 1u << 27,
CTRL0_MSR = 1u << 28,
AMD_SVM_ENABLE = 1 << 12,
AMD_SVM_ENABLE = 1 << 12,
AMD_EXIT_INVALID = 0xfd,
AMD_EXIT_INVALID = 0xfd,
};
enum {
@ -212,14 +218,12 @@ struct Vcpu : Genode::Thread
uint8_t _fpu_ep[512] __attribute__((aligned(0x10)));
uint8_t _fpu_vcpu[512] __attribute__((aligned(0x10)));
enum
{
enum {
VMEXIT_STARTUP = 0xfe,
VMEXIT_PAUSED = 0xff,
STACK_SIZE = 0x3000,
};
enum State {
NONE = 0,
PAUSE = 1,
@ -246,15 +250,15 @@ struct Vcpu : Genode::Thread
}
/* reserved ranged for state of vCPUs - see platform.cc */
Genode::addr_t const vcpu_addr = 0x1000 + 0x1000 * _id.id;
Fiasco::l4_vcpu_state_t * const vcpu = reinterpret_cast<Fiasco::l4_vcpu_state_t*>(vcpu_addr);
addr_t const vcpu_addr = 0x1000 + 0x1000 * _id.id;
Foc::l4_vcpu_state_t * const vcpu = reinterpret_cast<Foc::l4_vcpu_state_t*>(vcpu_addr);
if (!l4_vcpu_check_version(vcpu))
Genode::error("vCPU version mismatch kernel vs user-land - ",
vcpu->version, "!=",
(int)Fiasco::L4_VCPU_STATE_VERSION);
error("vCPU version mismatch kernel vs user-land - ",
vcpu->version, "!=",
(int)Foc::L4_VCPU_STATE_VERSION);
using namespace Fiasco;
using namespace Foc;
l4_vm_svm_vmcb_t *vmcb = reinterpret_cast<l4_vm_svm_vmcb_t *>(vcpu_addr + L4_VCPU_OFFSET_EXT_STATE);
void * vmcs = reinterpret_cast<void *>(vcpu_addr + L4_VCPU_OFFSET_EXT_STATE);
@ -265,15 +269,14 @@ struct Vcpu : Genode::Thread
state = Vm_state {};
/* initial startup VM exit to get valid VM state */
if (_vm_type == Virt::VMX) {
if (_vm_type == Virt::VMX)
_read_intel_state(state, vmcs, vcpu);
}
if (_vm_type == Virt::SVM) {
if (_vm_type == Virt::SVM)
_read_amd_state(state, vmcb, vcpu);
}
state.exit_reason = VMEXIT_STARTUP;
Genode::Signal_transmitter(_signal).submit();
Signal_transmitter(_signal).submit();
_handler_ready.down();
_wake_up.down();
@ -281,9 +284,9 @@ struct Vcpu : Genode::Thread
/*
* Fiasoc.OC peculiarities
*/
if (_vm_type == Virt::SVM) {
if (_vm_type == Virt::SVM)
state.efer.value(state.efer.value() | AMD_SVM_ENABLE);
}
if (_vm_type == Virt::SVM) {
vmcb->control_area.intercept_instruction0 = vmcb_ctrl0;
vmcb->control_area.intercept_instruction1 = vmcb_ctrl1;
@ -298,21 +301,22 @@ struct Vcpu : Genode::Thread
vmcb->state_save_area.g_pat = 0x7040600070406ull;
}
if (_vm_type == Virt::VMX) {
Fiasco::l4_vm_vmx_write(vmcs, Vmcs::CR0_MASK, vmcs_cr0_mask);
Fiasco::l4_vm_vmx_write(vmcs, Vmcs::CR4_MASK, vmcs_cr4_mask);
Fiasco::l4_vm_vmx_write(vmcs, Vmcs::CR4_SHADOW, 0);
Foc::l4_vm_vmx_write(vmcs, Vmcs::CR0_MASK, vmcs_cr0_mask);
Foc::l4_vm_vmx_write(vmcs, Vmcs::CR4_MASK, vmcs_cr4_mask);
Foc::l4_vm_vmx_write(vmcs, Vmcs::CR4_SHADOW, 0);
state.cr4.value(vmcs_cr4_set);
enum {
EXIT_SAVE_EFER = 1U << 20,
ENTRY_LOAD_EFER = 1U << 15,
};
Fiasco::l4_vm_vmx_write(vmcs, Vmcs::EXIT_CTRL, EXIT_SAVE_EFER);
Fiasco::l4_vm_vmx_write(vmcs, Vmcs::ENTRY_CTRL, ENTRY_LOAD_EFER);
Foc::l4_vm_vmx_write(vmcs, Vmcs::EXIT_CTRL, EXIT_SAVE_EFER);
Foc::l4_vm_vmx_write(vmcs, Vmcs::ENTRY_CTRL, ENTRY_LOAD_EFER);
}
if (_vm_type == Virt::SVM)
_write_amd_state(state, vmcb, vcpu);
if (_vm_type == Virt::VMX)
_write_intel_state(state, vmcs, vcpu);
@ -332,7 +336,7 @@ struct Vcpu : Genode::Thread
}
if (_state_current != RUN && _state_current != PAUSE) {
Genode::error("unknown vcpu state ", (int)_state_current);
error("unknown vcpu state ", (int)_state_current);
while (true) { _remote_mutex.acquire(); }
}
@ -362,7 +366,6 @@ struct Vcpu : Genode::Thread
});
asm volatile ("fxrstor %0" : : "m" (*_fpu_ep) : "memory");
/* got VM exit or interrupted by asynchronous signal */
uint64_t reason = 0;
@ -384,8 +387,8 @@ struct Vcpu : Genode::Thread
/* consume notification */
while (vcpu->sticky_flags) {
Fiasco::l4_cap_idx_t tid = native_thread().kcap;
Fiasco::l4_cap_idx_t irq = tid + Fiasco::TASK_VCPU_IRQ_CAP;
Foc::l4_cap_idx_t tid = native_thread().kcap;
Foc::l4_cap_idx_t irq = tid + Foc::TASK_VCPU_IRQ_CAP;
l4_irq_receive(irq, L4_IPC_RECV_TIMEOUT_0);
}
}
@ -396,7 +399,7 @@ struct Vcpu : Genode::Thread
}
if (_vm_type == Virt::VMX) {
reason = Fiasco::l4_vm_vmx_read_32(vmcs, Vmcs::EXI_REASON);
reason = Foc::l4_vm_vmx_read_32(vmcs, Vmcs::EXI_REASON);
{
Mutex::Guard guard(_remote_mutex);
@ -409,8 +412,8 @@ struct Vcpu : Genode::Thread
/* consume notification */
while (vcpu->sticky_flags) {
Fiasco::l4_cap_idx_t tid = native_thread().kcap;
Fiasco::l4_cap_idx_t irq = tid + Fiasco::TASK_VCPU_IRQ_CAP;
Foc::l4_cap_idx_t tid = native_thread().kcap;
Foc::l4_cap_idx_t irq = tid + Foc::TASK_VCPU_IRQ_CAP;
l4_irq_receive(irq, L4_IPC_RECV_TIMEOUT_0);
}
}
@ -421,7 +424,7 @@ struct Vcpu : Genode::Thread
}
/* notify VM handler */
Genode::Signal_transmitter(_signal).submit();
Signal_transmitter(_signal).submit();
/*
* Wait until VM handler is really really done,
@ -444,7 +447,7 @@ struct Vcpu : Genode::Thread
return ((value & 0x1f000) >> 4) | (value & 0xff); }
void _read_intel_state(Vm_state &state, void *vmcs,
Fiasco::l4_vcpu_state_t *vcpu)
Foc::l4_vcpu_state_t *vcpu)
{
state.ax.value(vcpu->r.ax);
state.cx.value(vcpu->r.cx);
@ -455,14 +458,14 @@ struct Vcpu : Genode::Thread
state.di.value(vcpu->r.di);
state.si.value(vcpu->r.si);
state.flags.value(Fiasco::l4_vm_vmx_read(vmcs, Vmcs::FLAGS));
state.flags.value(Foc::l4_vm_vmx_read(vmcs, Vmcs::FLAGS));
state.sp.value(Fiasco::l4_vm_vmx_read(vmcs, Vmcs::SP));
state.sp.value(Foc::l4_vm_vmx_read(vmcs, Vmcs::SP));
state.ip.value(Fiasco::l4_vm_vmx_read(vmcs, Vmcs::IP));
state.ip_len.value(Fiasco::l4_vm_vmx_read(vmcs, Vmcs::INST_LEN));
state.ip.value(Foc::l4_vm_vmx_read(vmcs, Vmcs::IP));
state.ip_len.value(Foc::l4_vm_vmx_read(vmcs, Vmcs::INST_LEN));
state.dr7.value(Fiasco::l4_vm_vmx_read(vmcs, Vmcs::DR7));
state.dr7.value(Foc::l4_vm_vmx_read(vmcs, Vmcs::DR7));
#ifdef __x86_64__
state.r8.value(vcpu->r.r8);
@ -476,32 +479,32 @@ struct Vcpu : Genode::Thread
#endif
{
addr_t const cr0 = Fiasco::l4_vm_vmx_read(vmcs, Vmcs::CR0);
addr_t const cr0_shadow = Fiasco::l4_vm_vmx_read(vmcs, Vmcs::CR0_SHADOW);
addr_t const cr0 = Foc::l4_vm_vmx_read(vmcs, Vmcs::CR0);
addr_t const cr0_shadow = Foc::l4_vm_vmx_read(vmcs, Vmcs::CR0_SHADOW);
state.cr0.value((cr0 & ~vmcs_cr0_mask) | (cr0_shadow & vmcs_cr0_mask));
if (state.cr0.value() != cr0_shadow)
Fiasco::l4_vm_vmx_write(vmcs, Vmcs::CR0_SHADOW, state.cr0.value());
Foc::l4_vm_vmx_write(vmcs, Vmcs::CR0_SHADOW, state.cr0.value());
}
unsigned const cr2 = Fiasco::l4_vm_vmx_get_cr2_index(vmcs);
state.cr2.value(Fiasco::l4_vm_vmx_read(vmcs, cr2));
state.cr3.value(Fiasco::l4_vm_vmx_read(vmcs, Vmcs::CR3));
unsigned const cr2 = Foc::l4_vm_vmx_get_cr2_index(vmcs);
state.cr2.value(Foc::l4_vm_vmx_read(vmcs, cr2));
state.cr3.value(Foc::l4_vm_vmx_read(vmcs, Vmcs::CR3));
{
addr_t const cr4 = Fiasco::l4_vm_vmx_read(vmcs, Vmcs::CR4);
addr_t const cr4_shadow = Fiasco::l4_vm_vmx_read(vmcs, Vmcs::CR4_SHADOW);
addr_t const cr4 = Foc::l4_vm_vmx_read(vmcs, Vmcs::CR4);
addr_t const cr4_shadow = Foc::l4_vm_vmx_read(vmcs, Vmcs::CR4_SHADOW);
state.cr4.value((cr4 & ~vmcs_cr4_mask) | (cr4_shadow & vmcs_cr4_mask));
if (state.cr4.value() != cr4_shadow)
Fiasco::l4_vm_vmx_write(vmcs, Vmcs::CR4_SHADOW,
Foc::l4_vm_vmx_write(vmcs, Vmcs::CR4_SHADOW,
state.cr4.value());
}
using Fiasco::l4_vm_vmx_read;
using Fiasco::l4_vm_vmx_read_16;
using Fiasco::l4_vm_vmx_read_32;
using Fiasco::l4_vm_vmx_read_nat;
typedef Genode::Vm_state::Segment Segment;
typedef Genode::Vm_state::Range Range;
using Foc::l4_vm_vmx_read;
using Foc::l4_vm_vmx_read_16;
using Foc::l4_vm_vmx_read_32;
using Foc::l4_vm_vmx_read_nat;
typedef Vm_state::Segment Segment;
typedef Vm_state::Range Range;
{
Segment cs { l4_vm_vmx_read_16(vmcs, Vmcs::CS_SEL),
@ -621,8 +624,8 @@ struct Vcpu : Genode::Thread
#endif
}
void _read_amd_state(Vm_state &state, Fiasco::l4_vm_svm_vmcb_t *vmcb,
Fiasco::l4_vcpu_state_t * const vcpu)
void _read_amd_state(Vm_state &state, Foc::l4_vm_svm_vmcb_t *vmcb,
Foc::l4_vcpu_state_t * const vcpu)
{
state.ax.value(vmcb->state_save_area.rax);
state.cx.value(vcpu->r.cx);
@ -668,7 +671,7 @@ struct Vcpu : Genode::Thread
vmcb_cr4_shadow = state.cr4.value();
}
typedef Genode::Vm_state::Segment Segment;
typedef Vm_state::Segment Segment;
state.cs.value(Segment{vmcb->state_save_area.cs.selector,
vmcb->state_save_area.cs.attrib,
@ -710,7 +713,7 @@ struct Vcpu : Genode::Thread
vmcb->state_save_area.ldtr.limit,
(addr_t)vmcb->state_save_area.ldtr.base});
typedef Genode::Vm_state::Range Range;
typedef Vm_state::Range Range;
state.gdtr.value(Range{(addr_t)vmcb->state_save_area.gdtr.base,
vmcb->state_save_area.gdtr.limit});
@ -750,24 +753,24 @@ struct Vcpu : Genode::Thread
if (state.pdpte_0.valid() || state.pdpte_1.valid() ||
state.pdpte_2.valid() || state.pdpte_3.valid()) {
Genode::error("pdpte not implemented");
error("pdpte not implemented");
}
if (state.star.valid() || state.lstar.valid() ||
state.fmask.valid() || state.kernel_gs_base.valid()) {
Genode::error("star, fstar, fmask, kernel_gs_base not implemented");
error("star, fstar, fmask, kernel_gs_base not implemented");
}
if (state.tpr.valid() || state.tpr_threshold.valid()) {
Genode::error("tpr not implemented");
error("tpr not implemented");
}
}
void _write_intel_state(Vm_state &state, void *vmcs,
Fiasco::l4_vcpu_state_t *vcpu)
Foc::l4_vcpu_state_t *vcpu)
{
using Fiasco::l4_vm_vmx_write;
using Foc::l4_vm_vmx_write;
if (state.ax.valid() || state.cx.valid() || state.dx.valid() ||
state.bx.valid()) {
@ -819,7 +822,7 @@ struct Vcpu : Genode::Thread
if (state.tpr.valid() || state.tpr_threshold.valid()) {
if (_show_error_unsupported_tpr) {
_show_error_unsupported_tpr = false;
Genode::error("TPR & TPR_THRESHOLD not supported on Fiasco.OC");
error("TPR & TPR_THRESHOLD not supported on Fiasco.OC");
}
}
@ -831,12 +834,12 @@ struct Vcpu : Genode::Thread
l4_vm_vmx_write(vmcs, Vmcs::CR0_SHADOW, state.cr0.value());
#if 0 /* if CPU has xsave feature bit ... see Vm::load_guest_xcr0 */
l4_vm_vmx_write(vmcs, Fiasco::L4_VM_VMX_VMCS_XCR0, state.cr0.value());
l4_vm_vmx_write(vmcs, Foc::L4_VM_VMX_VMCS_XCR0, state.cr0.value());
#endif
}
if (state.cr2.valid()) {
unsigned const cr2 = Fiasco::l4_vm_vmx_get_cr2_index(vmcs);
unsigned const cr2 = Foc::l4_vm_vmx_get_cr2_index(vmcs);
l4_vm_vmx_write(vmcs, cr2, state.cr2.value());
}
@ -852,10 +855,13 @@ struct Vcpu : Genode::Thread
if (state.inj_info.valid() || state.inj_error.valid()) {
addr_t ctrl_0 = state.ctrl_primary.valid() ?
state.ctrl_primary.value() :
Fiasco::l4_vm_vmx_read(vmcs, Vmcs::CTRL_0);
Foc::l4_vm_vmx_read(vmcs, Vmcs::CTRL_0);
if (state.inj_info.value() & 0x2000)
Genode::warning("unimplemented ", state.inj_info.value() & 0x1000, " ", state.inj_info.value() & 0x2000, " ", Genode::Hex(ctrl_0), " ", Genode::Hex(state.ctrl_secondary.value()));
warning("unimplemented ", state.inj_info.value() & 0x1000, " ",
state.inj_info.value() & 0x2000, " ",
Hex(ctrl_0), " ",
Hex(state.ctrl_secondary.value()));
if (state.inj_info.value() & 0x1000)
ctrl_0 |= Vmcs::IRQ_WINDOW;
@ -972,7 +978,7 @@ struct Vcpu : Genode::Thread
{
if (_show_error_unsupported_pdpte) {
_show_error_unsupported_pdpte = false;
Genode::error("PDPTE 0/1/2/3 not supported on Fiasco.OC");
error("PDPTE 0/1/2/3 not supported on Fiasco.OC");
}
}
@ -987,8 +993,8 @@ struct Vcpu : Genode::Thread
state.sysenter_ip.value());
}
void _write_amd_state(Vm_state &state, Fiasco::l4_vm_svm_vmcb_t *vmcb,
Fiasco::l4_vcpu_state_t *vcpu)
void _write_amd_state(Vm_state &state, Foc::l4_vm_svm_vmcb_t *vmcb,
Foc::l4_vcpu_state_t *vcpu)
{
if (state.ax.valid() || state.cx.valid() || state.dx.valid() ||
state.bx.valid()) {
@ -1028,12 +1034,12 @@ struct Vcpu : Genode::Thread
if (state.star.value() || state.lstar.value() ||
state.fmask.value() || state.kernel_gs_base.value())
Genode::error(__LINE__, " not implemented");
error(__LINE__, " not implemented");
if (state.tpr.valid() || state.tpr_threshold.valid()) {
if (_show_error_unsupported_tpr) {
_show_error_unsupported_tpr = false;
Genode::error("TPR & TPR_THRESHOLD not supported on Fiasco.OC");
error("TPR & TPR_THRESHOLD not supported on Fiasco.OC");
}
}
@ -1173,7 +1179,7 @@ struct Vcpu : Genode::Thread
{
if (_show_error_unsupported_pdpte) {
_show_error_unsupported_pdpte = false;
Genode::error("PDPTE 0/1/2/3 not supported on Fiasco.OC");
error("PDPTE 0/1/2/3 not supported on Fiasco.OC");
}
}
@ -1200,14 +1206,15 @@ struct Vcpu : Genode::Thread
bool match(Vm_session_client::Vcpu_id id) { return id.id == _id.id; }
Genode::Vm_session_client::Vcpu_id id() const { return _id; }
void id(Genode::Vm_session_client::Vcpu_id id) { _id = id; }
Vm_session_client::Vcpu_id id() const { return _id; }
void id(Vm_session_client::Vcpu_id id) { _id = id; }
void assign_ds_state(Region_map &rm, Dataspace_capability cap)
{
_state = rm.attach(cap);
_task = *reinterpret_cast<Fiasco::l4_cap_idx_t *>(_state);
*reinterpret_cast<Fiasco::l4_cap_idx_t *>(_state) = 0UL;
_task = *reinterpret_cast<Foc::l4_cap_idx_t *>(_state);
*reinterpret_cast<Foc::l4_cap_idx_t *>(_state) = 0UL;
}
void resume()
@ -1233,9 +1240,9 @@ struct Vcpu : Genode::Thread
_state_request = PAUSE;
/* recall vCPU */
Fiasco::l4_cap_idx_t tid = native_thread().kcap;
Fiasco::l4_cap_idx_t irq = tid + Fiasco::TASK_VCPU_IRQ_CAP;
Fiasco::l4_irq_trigger(irq);
Foc::l4_cap_idx_t tid = native_thread().kcap;
Foc::l4_cap_idx_t irq = tid + Foc::TASK_VCPU_IRQ_CAP;
Foc::l4_irq_trigger(irq);
if (_state_current == NONE)
_wake_up.up();
@ -1249,11 +1256,11 @@ struct Vcpu : Genode::Thread
};
static enum Virt virt_type(Genode::Env &env)
static enum Virt virt_type(Env &env)
{
try {
Genode::Attached_rom_dataspace const info(env, "platform_info");
Genode::Xml_node const features = info.xml().sub_node("hardware").sub_node("features");
Attached_rom_dataspace const info(env, "platform_info");
Xml_node const features = info.xml().sub_node("hardware").sub_node("features");
if (features.attribute_value("svm", false))
return Virt::SVM;
@ -1272,7 +1279,7 @@ Vm_session_client::create_vcpu(Allocator &alloc, Env &env,
{
enum Virt vm_type = virt_type(env);
if (vm_type == Virt::UNKNOWN) {
Genode::error("unsupported hardware virtualisation");
error("unsupported hardware virtualisation");
return Vm_session::Vcpu_id();
}
@ -1304,6 +1311,7 @@ Vm_session_client::create_vcpu(Allocator &alloc, Env &env,
return vcpu->id();
}
void Vm_session_client::run(Vcpu_id vcpu_id)
{
vcpus.for_each([&] (Vcpu &vcpu) {
@ -1312,6 +1320,7 @@ void Vm_session_client::run(Vcpu_id vcpu_id)
});
}
void Vm_session_client::pause(Vm_session_client::Vcpu_id vcpu_id)
{
vcpus.for_each([&] (Vcpu &vcpu) {
@ -1322,6 +1331,7 @@ void Vm_session_client::pause(Vm_session_client::Vcpu_id vcpu_id)
});
}
Dataspace_capability Vm_session_client::cpu_state(Vcpu_id vcpu_id)
{
Dataspace_capability cap;
@ -1334,6 +1344,7 @@ Dataspace_capability Vm_session_client::cpu_state(Vcpu_id vcpu_id)
return cap;
}
Vm_session::~Vm_session()
{
vcpus.for_each([&] (Vcpu &vc) {

View File

@ -22,7 +22,7 @@
#include <base/internal/cap_map.h> /* cap_idx_alloc */
using namespace Genode;
using namespace Fiasco;
using namespace Foc;
struct Main { Main(Env &env); };
@ -34,15 +34,15 @@ Main::Main(Env &env)
enum { COUNT = 1000 };
Cap_index* idx = cap_idx_alloc().alloc_range(COUNT);
Fiasco::l4_cap_idx_t tid = Capability_space::kcap(env.pd_session_cap());
Cap_index *idx = cap_idx_alloc().alloc_range(COUNT);
Foc::l4_cap_idx_t tid = Capability_space::kcap(env.pd_session_cap());
/* try the first 1000 local name IDs */
for (int local_name = 0; local_name < COUNT; local_name++, idx++) {
idx->id(local_name);
l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP,
l4_obj_fpage(tid, 0, L4_FPAGE_RWX),
idx->kcap() | L4_ITEM_MAP);
l4_obj_fpage(tid, 0, L4_FPAGE_RWX),
idx->kcap() | L4_ITEM_MAP);
Log_session_capability log_session_cap =
reinterpret_cap_cast<Log_session>(Native_capability(idx));