mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-16 07:27:35 +00:00
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:
parent
0209a2465d
commit
70ff3d9c90
@ -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);
|
||||
|
||||
} }
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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_ */
|
||||
|
36
repos/base-foc/include/foc/syscall.h
Normal file
36
repos/base-foc/include/foc/syscall.h
Normal 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_ */
|
@ -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_ */
|
||||
|
@ -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); }
|
||||
|
@ -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_ */
|
||||
|
@ -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; }
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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;
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
namespace Genode { struct Pager_object_exception_state; }
|
||||
|
||||
|
||||
struct Genode::Pager_object_exception_state
|
||||
{
|
||||
Mutex mutex { };
|
||||
|
@ -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 ®ion_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 ®ion_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_ */
|
||||
|
@ -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_ */
|
||||
|
@ -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_ */
|
||||
|
@ -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; }
|
||||
|
@ -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 **
|
||||
**************************/
|
||||
|
@ -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)
|
||||
{ }
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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'.
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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 ®_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 */
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 &) { }
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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); });
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
|
@ -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))
|
||||
|
@ -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),
|
||||
|
@ -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_ */
|
||||
|
@ -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_ */
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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_ */
|
||||
|
@ -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));
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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); }
|
||||
|
@ -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();
|
||||
|
@ -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]);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user