mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 22:47:50 +00:00
nova: remove echo thread in core
and replace by remote delegate syscall Fixes #2895
This commit is contained in:
parent
117b932176
commit
bac7ba6639
@ -14,7 +14,6 @@ SRC_CC += stack_area.cc \
|
|||||||
dataspace_component.cc \
|
dataspace_component.cc \
|
||||||
default_log.cc \
|
default_log.cc \
|
||||||
dump_alloc.cc \
|
dump_alloc.cc \
|
||||||
echo.cc \
|
|
||||||
io_mem_session_component.cc \
|
io_mem_session_component.cc \
|
||||||
io_mem_session_support.cc \
|
io_mem_session_support.cc \
|
||||||
io_port_session_component.cc \
|
io_port_session_component.cc \
|
||||||
|
@ -78,7 +78,8 @@ Core_region_map::attach(Dataspace_capability ds_cap, size_t,
|
|||||||
Nova::Utcb * const utcb = reinterpret_cast<Nova::Utcb *>(Thread::myself()->utcb());
|
Nova::Utcb * const utcb = reinterpret_cast<Nova::Utcb *>(Thread::myself()->utcb());
|
||||||
const Nova::Rights rights(true, writeable && ds->writable(), executable);
|
const Nova::Rights rights(true, writeable && ds->writable(), executable);
|
||||||
|
|
||||||
if (map_local(utcb, ds->phys_addr(), reinterpret_cast<addr_t>(virt_ptr),
|
if (map_local(platform_specific()->core_pd_sel(), utcb,
|
||||||
|
ds->phys_addr(), reinterpret_cast<addr_t>(virt_ptr),
|
||||||
page_rounded_size >> get_page_size_log2(), rights, true)) {
|
page_rounded_size >> get_page_size_log2(), rights, true)) {
|
||||||
platform()->region_alloc()->free(virt_ptr, page_rounded_size);
|
platform()->region_alloc()->free(virt_ptr, page_rounded_size);
|
||||||
throw Out_of_ram();
|
throw Out_of_ram();
|
||||||
|
@ -1,94 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Echo implementation
|
|
||||||
* \author Norman Feske
|
|
||||||
* \author Alexander Boettcher
|
|
||||||
* \date 2010-01-19
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2010-2017 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* core-local includes */
|
|
||||||
#include <platform.h>
|
|
||||||
|
|
||||||
/* local includes */
|
|
||||||
#include <echo.h>
|
|
||||||
#include <nova_util.h>
|
|
||||||
|
|
||||||
enum {
|
|
||||||
ECHO_STACK_SIZE = 512,
|
|
||||||
ECHO_GLOBAL = false,
|
|
||||||
ECHO_EXC_BASE = 0,
|
|
||||||
ECHO_LOG2_COUNT = 1 /* selector for EC and out-of-memory portal */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
inline void *echo_stack_top()
|
|
||||||
{
|
|
||||||
static char echo_stack[ECHO_STACK_SIZE];
|
|
||||||
return &echo_stack[ECHO_STACK_SIZE - sizeof(long)];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IDC handler for the echo portal, executed by the echo EC
|
|
||||||
*/
|
|
||||||
static void echo_reply()
|
|
||||||
{
|
|
||||||
/* collect map information from calling thread, sent as 3 words */
|
|
||||||
Nova::Crd snd_rcv(echo()->utcb()->msg()[0]);
|
|
||||||
Nova::mword_t offset = echo()->utcb()->msg()[1];
|
|
||||||
bool kern_pd = echo()->utcb()->msg()[2];
|
|
||||||
bool dma_mem = echo()->utcb()->msg()[3];
|
|
||||||
bool write_combined = echo()->utcb()->msg()[4];
|
|
||||||
|
|
||||||
/* reset message transfer descriptor */
|
|
||||||
echo()->utcb()->set_msg_word(0);
|
|
||||||
/* append capability-range as message-transfer item */
|
|
||||||
bool res = echo()->utcb()->append_item(snd_rcv, offset, kern_pd, false,
|
|
||||||
false, dma_mem, write_combined);
|
|
||||||
|
|
||||||
/* set return code, 0 means failure */
|
|
||||||
echo()->utcb()->msg()[0] = res;
|
|
||||||
echo()->utcb()->items += 1;
|
|
||||||
|
|
||||||
/* during reply the mapping will be established */
|
|
||||||
Nova::reply(echo_stack_top());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Echo::Echo(Genode::addr_t utcb_addr)
|
|
||||||
:
|
|
||||||
_ec_sel(Genode::cap_map()->insert(ECHO_LOG2_COUNT)),
|
|
||||||
_pt_sel(Genode::cap_map()->insert()),
|
|
||||||
_utcb((Nova::Utcb *)utcb_addr)
|
|
||||||
{
|
|
||||||
using namespace Nova;
|
|
||||||
|
|
||||||
extern Genode::addr_t __initial_sp;
|
|
||||||
Hip const * const hip = reinterpret_cast<Hip *>(__initial_sp);
|
|
||||||
|
|
||||||
/* create echo EC */
|
|
||||||
Genode::addr_t const core_pd_sel = hip->sel_exc;
|
|
||||||
uint8_t res = create_ec(_ec_sel, core_pd_sel, boot_cpu(), utcb_addr,
|
|
||||||
reinterpret_cast<mword_t>(echo_stack_top()),
|
|
||||||
ECHO_EXC_BASE, ECHO_GLOBAL);
|
|
||||||
|
|
||||||
/* make error condition visible by raising an unhandled page fault */
|
|
||||||
if (res != Nova::NOVA_OK) { *reinterpret_cast<unsigned *>(0) = 0xdead; }
|
|
||||||
|
|
||||||
/* set up echo portal to ourself */
|
|
||||||
res = create_pt(_pt_sel, core_pd_sel, _ec_sel, Mtd(0), (mword_t)echo_reply);
|
|
||||||
if (res != Nova::NOVA_OK) { *reinterpret_cast<unsigned *>(0) = 0xdead; }
|
|
||||||
revoke(Obj_crd(_pt_sel, 0, Obj_crd::RIGHT_PT_CTRL));
|
|
||||||
|
|
||||||
/* echo thread doesn't receive anything, it transfers items during reply */
|
|
||||||
utcb()->crd_rcv = utcb()->crd_xlt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Echo *echo() { static Echo inst(Echo::ECHO_UTCB_ADDR); return &inst; }
|
|
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Echo interface
|
|
||||||
* \author Norman Feske
|
|
||||||
* \date 2010-01-19
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2010-2017 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 _CORE__INCLUDE__ECHO_H_
|
|
||||||
#define _CORE__INCLUDE__ECHO_H_
|
|
||||||
|
|
||||||
/* NOVA includes */
|
|
||||||
#include <nova/syscalls.h>
|
|
||||||
|
|
||||||
class Echo
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
int _ec_sel; /* execution context */
|
|
||||||
int _pt_sel; /* portal */
|
|
||||||
Nova::Utcb *_utcb;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum {
|
|
||||||
ECHO_UTCB_ADDR = 0xbff00000,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* \param utcb_addr designated UTCB location for echo EC
|
|
||||||
*/
|
|
||||||
Echo(Genode::addr_t utcb_addr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UTCB of echo execution context
|
|
||||||
*/
|
|
||||||
Nova::Utcb *utcb() { return _utcb; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Capability selector for portal to echo
|
|
||||||
*/
|
|
||||||
int pt_sel() { return _pt_sel; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get single 'Echo' instance
|
|
||||||
*/
|
|
||||||
Echo *echo();
|
|
||||||
|
|
||||||
#endif /* _CORE__INCLUDE__ECHO_H_ */
|
|
@ -37,7 +37,8 @@ namespace Genode {
|
|||||||
inline bool map_local(addr_t from_phys, addr_t to_virt, size_t num_pages,
|
inline bool map_local(addr_t from_phys, addr_t to_virt, size_t num_pages,
|
||||||
bool read = true, bool write = true, bool exec = true)
|
bool read = true, bool write = true, bool exec = true)
|
||||||
{
|
{
|
||||||
return (::map_local((Nova::Utcb *)Thread::myself()->utcb(),
|
return (::map_local(platform_specific()->core_pd_sel(),
|
||||||
|
(Nova::Utcb *)Thread::myself()->utcb(),
|
||||||
from_phys, to_virt, num_pages,
|
from_phys, to_virt, num_pages,
|
||||||
Nova::Rights(read, write, exec), true) == 0);
|
Nova::Rights(read, write, exec), true) == 0);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include <nova/syscalls.h>
|
#include <nova/syscalls.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <echo.h>
|
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,31 +54,22 @@ inline Genode::addr_t boot_cpu()
|
|||||||
* target
|
* target
|
||||||
* \param kern_pd Whether to map the items from the kernel or from core
|
* \param kern_pd Whether to map the items from the kernel or from core
|
||||||
* \param dma_mem Whether the memory is usable for DMA or not
|
* \param dma_mem Whether the memory is usable for DMA or not
|
||||||
*
|
|
||||||
* This functions sends a message from the calling EC to the echo EC.
|
|
||||||
* The calling EC opens a receive window and the echo EC creates a transfer
|
|
||||||
* item of the message and replies. The kernel will map during the reply
|
|
||||||
* from the echo EC to the calling EC.
|
|
||||||
*/
|
*/
|
||||||
static int map_local(Nova::Utcb *utcb, Nova::Crd src_crd, Nova::Crd dst_crd,
|
static int map_local(Genode::addr_t const pd, Nova::Utcb * const utcb,
|
||||||
bool kern_pd = false, bool dma_mem = false,
|
Nova::Crd const src_crd, Nova::Crd const dst_crd,
|
||||||
bool write_combined = false)
|
bool const kern_pd = false, bool const dma_mem = false,
|
||||||
|
bool const write_combined = false)
|
||||||
{
|
{
|
||||||
/* open receive window at current EC */
|
/* asynchronously map capabilities */
|
||||||
utcb->crd_rcv = dst_crd;
|
utcb->set_msg_word(0);
|
||||||
|
|
||||||
/* tell echo thread what to map */
|
/* ignore return value as one item always fits into the utcb */
|
||||||
utcb->msg()[0] = src_crd.value();
|
bool const ok = utcb->append_item(src_crd, 0, kern_pd, false, false,
|
||||||
utcb->msg()[1] = 0;
|
dma_mem, write_combined);
|
||||||
utcb->msg()[2] = kern_pd;
|
(void)ok;
|
||||||
utcb->msg()[3] = dma_mem;
|
|
||||||
utcb->msg()[4] = write_combined;
|
|
||||||
utcb->set_msg_word(5);
|
|
||||||
|
|
||||||
/* establish the mapping via a portal traversal during reply phase */
|
Nova::uint8_t res = Nova::delegate(pd, pd, dst_crd);
|
||||||
Nova::uint8_t res = Nova::call(echo()->pt_sel());
|
if (res != Nova::NOVA_OK) {
|
||||||
if (res != Nova::NOVA_OK || utcb->msg_words() != 1 || !utcb->msg()[0] ||
|
|
||||||
utcb->msg_items() != 1) {
|
|
||||||
|
|
||||||
typedef Genode::Hex Hex;
|
typedef Genode::Hex Hex;
|
||||||
error("map_local failed ",
|
error("map_local failed ",
|
||||||
@ -103,12 +93,17 @@ static int map_local(Nova::Utcb *utcb, Nova::Crd src_crd, Nova::Crd dst_crd,
|
|||||||
static inline int unmap_local(Nova::Crd crd, bool self = true) {
|
static inline int unmap_local(Nova::Crd crd, bool self = true) {
|
||||||
return Nova::revoke(crd, self); }
|
return Nova::revoke(crd, self); }
|
||||||
|
|
||||||
inline int map_local_phys_to_virt(Nova::Utcb *utcb, Nova::Crd src,
|
inline int map_local_phys_to_virt(Nova::Utcb * const utcb, Nova::Crd const src,
|
||||||
Nova::Crd dst) {
|
Nova::Crd const dst, Genode::addr_t const pd)
|
||||||
return map_local(utcb, src, dst, true); }
|
{
|
||||||
|
return map_local(pd, utcb, src, dst, true);
|
||||||
|
}
|
||||||
|
|
||||||
inline int map_local_one_to_one(Nova::Utcb *utcb, Nova::Crd crd) {
|
inline int map_local_one_to_one(Nova::Utcb * const utcb, Nova::Crd const crd,
|
||||||
return map_local(utcb, crd, crd, true); }
|
Genode::addr_t const pd)
|
||||||
|
{
|
||||||
|
return map_local(pd, utcb, crd, crd, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,7 +128,7 @@ lsb_bit(unsigned long const &value, unsigned char const shift = 0)
|
|||||||
* \param to_start local virtual destination address
|
* \param to_start local virtual destination address
|
||||||
* \param num_pages number of pages to map
|
* \param num_pages number of pages to map
|
||||||
*/
|
*/
|
||||||
inline int map_local(Nova::Utcb *utcb,
|
inline int map_local(Genode::addr_t const pd, Nova::Utcb *utcb,
|
||||||
Genode::addr_t from_start, Genode::addr_t to_start,
|
Genode::addr_t from_start, Genode::addr_t to_start,
|
||||||
Genode::size_t num_pages,
|
Genode::size_t num_pages,
|
||||||
Nova::Rights const &permission,
|
Nova::Rights const &permission,
|
||||||
@ -169,7 +164,7 @@ inline int map_local(Nova::Utcb *utcb,
|
|||||||
if ((to_end - to_curr) < (1UL << order))
|
if ((to_end - to_curr) < (1UL << order))
|
||||||
order = log2(to_end - to_curr);
|
order = log2(to_end - to_curr);
|
||||||
|
|
||||||
int const res = map_local(utcb,
|
int const res = map_local(pd, utcb,
|
||||||
Mem_crd((from_curr >> 12), order - get_page_size_log2(), permission),
|
Mem_crd((from_curr >> 12), order - get_page_size_log2(), permission),
|
||||||
Mem_crd((to_curr >> 12), order - get_page_size_log2(), permission),
|
Mem_crd((to_curr >> 12), order - get_page_size_log2(), permission),
|
||||||
kern_pd, dma_mem, write_combined);
|
kern_pd, dma_mem, write_combined);
|
||||||
|
@ -84,7 +84,7 @@ static bool msi(Genode::addr_t irq_sel, Genode::addr_t phys_mem,
|
|||||||
Nova::Mem_crd virt_crd(virt_addr >> 12, 0, Rights(true, false, false));
|
Nova::Mem_crd virt_crd(virt_addr >> 12, 0, Rights(true, false, false));
|
||||||
Utcb * utcb = reinterpret_cast<Utcb *>(Thread::myself()->utcb());
|
Utcb * utcb = reinterpret_cast<Utcb *>(Thread::myself()->utcb());
|
||||||
|
|
||||||
if (map_local_phys_to_virt(utcb, phys_crd, virt_crd)) {
|
if (map_local_phys_to_virt(utcb, phys_crd, virt_crd, platform_specific()->core_pd_sel())) {
|
||||||
platform()->region_alloc()->free(virt, 4096);
|
platform()->region_alloc()->free(virt, 4096);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -142,7 +142,8 @@ void Irq_object::start(unsigned irq, Genode::addr_t const device_phys)
|
|||||||
Obj_crd dst(irq_sel(), 0);
|
Obj_crd dst(irq_sel(), 0);
|
||||||
enum { MAP_FROM_KERNEL_TO_CORE = true };
|
enum { MAP_FROM_KERNEL_TO_CORE = true };
|
||||||
|
|
||||||
int ret = map_local((Nova::Utcb *)Thread::myself()->utcb(),
|
int ret = map_local(platform_specific()->core_pd_sel(),
|
||||||
|
(Nova::Utcb *)Thread::myself()->utcb(),
|
||||||
src, dst, MAP_FROM_KERNEL_TO_CORE);
|
src, dst, MAP_FROM_KERNEL_TO_CORE);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
error("getting IRQ from kernel failed - ", irq);
|
error("getting IRQ from kernel failed - ", irq);
|
||||||
|
@ -86,7 +86,8 @@ addr_t Platform::_map_pages(addr_t const phys_addr, addr_t const pages,
|
|||||||
|
|
||||||
addr_t const core_local_addr = reinterpret_cast<addr_t>(core_local_ptr);
|
addr_t const core_local_addr = reinterpret_cast<addr_t>(core_local_ptr);
|
||||||
|
|
||||||
int res = map_local(__main_thread_utcb, phys_addr, core_local_addr, pages,
|
int res = map_local(_core_pd_sel, __main_thread_utcb, phys_addr,
|
||||||
|
core_local_addr, pages,
|
||||||
Nova::Rights(true, true, false), true);
|
Nova::Rights(true, true, false), true);
|
||||||
|
|
||||||
return res ? 0 : core_local_addr;
|
return res ? 0 : core_local_addr;
|
||||||
@ -219,7 +220,7 @@ static void startup_handler()
|
|||||||
|
|
||||||
static addr_t init_core_page_fault_handler(addr_t const core_pd_sel)
|
static addr_t init_core_page_fault_handler(addr_t const core_pd_sel)
|
||||||
{
|
{
|
||||||
/* create echo EC */
|
/* create fault handler EC for core main thread */
|
||||||
enum {
|
enum {
|
||||||
GLOBAL = false,
|
GLOBAL = false,
|
||||||
EXC_BASE = 0
|
EXC_BASE = 0
|
||||||
@ -307,12 +308,13 @@ Platform::Platform() :
|
|||||||
|
|
||||||
/* locally map the whole I/O port range */
|
/* locally map the whole I/O port range */
|
||||||
enum { ORDER_64K = 16 };
|
enum { ORDER_64K = 16 };
|
||||||
map_local_one_to_one(__main_thread_utcb, Io_crd(0, ORDER_64K));
|
map_local_one_to_one(__main_thread_utcb, Io_crd(0, ORDER_64K), _core_pd_sel);
|
||||||
/* map BDA region, console reads IO ports at BDA_VIRT_ADDR + 0x400 */
|
/* map BDA region, console reads IO ports at BDA_VIRT_ADDR + 0x400 */
|
||||||
enum { BDA_PHY = 0x0U, BDA_VIRT = 0x1U, BDA_VIRT_ADDR = 0x1000U };
|
enum { BDA_PHY = 0x0U, BDA_VIRT = 0x1U, BDA_VIRT_ADDR = 0x1000U };
|
||||||
map_local_phys_to_virt(__main_thread_utcb,
|
map_local_phys_to_virt(__main_thread_utcb,
|
||||||
Mem_crd(BDA_PHY, 0, Rights(true, false, false)),
|
Mem_crd(BDA_PHY, 0, Rights(true, false, false)),
|
||||||
Mem_crd(BDA_VIRT, 0, Rights(true, false, false)));
|
Mem_crd(BDA_VIRT, 0, Rights(true, false, false)),
|
||||||
|
_core_pd_sel);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -324,7 +326,7 @@ Platform::Platform() :
|
|||||||
* we do this that early, because Core_mem_allocator uses
|
* we do this that early, because Core_mem_allocator uses
|
||||||
* the main_thread_utcb very early to establish mappings
|
* the main_thread_utcb very early to establish mappings
|
||||||
*/
|
*/
|
||||||
if (map_local(__main_thread_utcb, (addr_t)__main_thread_utcb,
|
if (map_local(_core_pd_sel, __main_thread_utcb, (addr_t)__main_thread_utcb,
|
||||||
(addr_t)main_thread_utcb(), 1, Rights(true, true, false))) {
|
(addr_t)main_thread_utcb(), 1, Rights(true, true, false))) {
|
||||||
error("could not remap utcb of main thread");
|
error("could not remap utcb of main thread");
|
||||||
nova_die();
|
nova_die();
|
||||||
@ -359,7 +361,7 @@ Platform::Platform() :
|
|||||||
error("unaligned sc_idle_base value ", Hex(sc_idle_base));
|
error("unaligned sc_idle_base value ", Hex(sc_idle_base));
|
||||||
nova_die();
|
nova_die();
|
||||||
}
|
}
|
||||||
if (map_local(__main_thread_utcb, Obj_crd(0, log2cpu),
|
if (map_local(_core_pd_sel, __main_thread_utcb, Obj_crd(0, log2cpu),
|
||||||
Obj_crd(sc_idle_base, log2cpu), true))
|
Obj_crd(sc_idle_base, log2cpu), true))
|
||||||
nova_die();
|
nova_die();
|
||||||
|
|
||||||
@ -388,7 +390,7 @@ Platform::Platform() :
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* set up page fault handler for core - for debugging */
|
/* set up page fault handler for core - for debugging */
|
||||||
addr_t const ec_echo_sel = init_core_page_fault_handler(core_pd_sel());
|
addr_t const ec_core_exc_sel = init_core_page_fault_handler(core_pd_sel());
|
||||||
|
|
||||||
if (verbose_boot_info) {
|
if (verbose_boot_info) {
|
||||||
if (hip->has_feature_vmx())
|
if (hip->has_feature_vmx())
|
||||||
@ -458,10 +460,6 @@ Platform::Platform() :
|
|||||||
region_alloc()->remove_range(CORE_PAGER_UTCB_ADDR - get_page_size(),
|
region_alloc()->remove_range(CORE_PAGER_UTCB_ADDR - get_page_size(),
|
||||||
get_page_size() * 3);
|
get_page_size() * 3);
|
||||||
|
|
||||||
/* exclude utcb of echo thread + empty guard pages before and after */
|
|
||||||
region_alloc()->remove_range(Echo::ECHO_UTCB_ADDR - get_page_size(),
|
|
||||||
get_page_size() * 3);
|
|
||||||
|
|
||||||
/* exclude utcb of main thread and hip + empty guard pages before and after */
|
/* exclude utcb of main thread and hip + empty guard pages before and after */
|
||||||
region_alloc()->remove_range((addr_t)__main_thread_utcb - get_page_size(),
|
region_alloc()->remove_range((addr_t)__main_thread_utcb - get_page_size(),
|
||||||
get_page_size() * 4);
|
get_page_size() * 4);
|
||||||
@ -469,7 +467,7 @@ Platform::Platform() :
|
|||||||
/* sanity checks */
|
/* sanity checks */
|
||||||
addr_t check [] = {
|
addr_t check [] = {
|
||||||
reinterpret_cast<addr_t>(__main_thread_utcb), CORE_PAGER_UTCB_ADDR,
|
reinterpret_cast<addr_t>(__main_thread_utcb), CORE_PAGER_UTCB_ADDR,
|
||||||
Echo::ECHO_UTCB_ADDR, BDA_VIRT_ADDR
|
BDA_VIRT_ADDR
|
||||||
};
|
};
|
||||||
|
|
||||||
for (unsigned i = 0; i < sizeof(check) / sizeof(check[0]); i++) {
|
for (unsigned i = 0; i < sizeof(check) / sizeof(check[0]); i++) {
|
||||||
@ -826,7 +824,7 @@ Platform::Platform() :
|
|||||||
"cross");
|
"cross");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add echo thread and EC root thread to trace sources */
|
/* add exception handler EC for core and EC root thread to trace sources */
|
||||||
struct Core_trace_source : public Trace::Source::Info_accessor,
|
struct Core_trace_source : public Trace::Source::Info_accessor,
|
||||||
private Trace::Control,
|
private Trace::Control,
|
||||||
private Trace::Source
|
private Trace::Source
|
||||||
@ -867,7 +865,7 @@ Platform::Platform() :
|
|||||||
new (core_mem_alloc())
|
new (core_mem_alloc())
|
||||||
Core_trace_source(Trace::sources(),
|
Core_trace_source(Trace::sources(),
|
||||||
Affinity::Location(0, 0, _cpus.width(), 1),
|
Affinity::Location(0, 0, _cpus.width(), 1),
|
||||||
ec_echo_sel, "echo");
|
ec_core_exc_sel, "core_fault");
|
||||||
|
|
||||||
new (core_mem_alloc())
|
new (core_mem_alloc())
|
||||||
Core_trace_source(Trace::sources(),
|
Core_trace_source(Trace::sources(),
|
||||||
@ -899,7 +897,12 @@ unsigned Platform::kernel_cpu_id(unsigned genode_cpu_id)
|
|||||||
bool Mapped_mem_allocator::_map_local(addr_t virt_addr, addr_t phys_addr,
|
bool Mapped_mem_allocator::_map_local(addr_t virt_addr, addr_t phys_addr,
|
||||||
unsigned size)
|
unsigned size)
|
||||||
{
|
{
|
||||||
map_local((Utcb *)Thread::myself()->utcb(), phys_addr,
|
/* platform_specific()->core_pd_sel() deadlocks if called from platform constructor */
|
||||||
|
Hip const * const hip = (Hip const * const)__initial_sp;
|
||||||
|
Genode::addr_t const core_pd_sel = hip->sel_exc;
|
||||||
|
|
||||||
|
map_local(core_pd_sel,
|
||||||
|
(Utcb *)Thread::myself()->utcb(), phys_addr,
|
||||||
virt_addr, size / get_page_size(),
|
virt_addr, size / get_page_size(),
|
||||||
Rights(true, true, false), true);
|
Rights(true, true, false), true);
|
||||||
return true;
|
return true;
|
||||||
|
@ -91,9 +91,10 @@ int Platform_thread::start(void *ip, void *sp)
|
|||||||
|
|
||||||
Utcb * const utcb = reinterpret_cast<Utcb *>(Thread::myself()->utcb());
|
Utcb * const utcb = reinterpret_cast<Utcb *>(Thread::myself()->utcb());
|
||||||
unsigned const kernel_cpu_id = platform_specific()->kernel_cpu_id(_location.xpos());
|
unsigned const kernel_cpu_id = platform_specific()->kernel_cpu_id(_location.xpos());
|
||||||
|
addr_t const source_pd = platform_specific()->core_pd_sel();
|
||||||
|
|
||||||
addr_t const pt_oom = _pager->get_oom_portal();
|
addr_t const pt_oom = _pager->get_oom_portal();
|
||||||
if (!pt_oom || map_local(utcb,
|
if (!pt_oom || map_local(source_pd, utcb,
|
||||||
Obj_crd(pt_oom, 0), Obj_crd(_sel_pt_oom(), 0))) {
|
Obj_crd(pt_oom, 0), Obj_crd(_sel_pt_oom(), 0))) {
|
||||||
error("setup of out-of-memory notification portal - failed");
|
error("setup of out-of-memory notification portal - failed");
|
||||||
return -8;
|
return -8;
|
||||||
@ -162,7 +163,7 @@ int Platform_thread::start(void *ip, void *sp)
|
|||||||
|
|
||||||
/* remap exception portals for first thread */
|
/* remap exception portals for first thread */
|
||||||
for (unsigned i = 0; i < sizeof(remap_dst)/sizeof(remap_dst[0]); i++) {
|
for (unsigned i = 0; i < sizeof(remap_dst)/sizeof(remap_dst[0]); i++) {
|
||||||
if (map_local(utcb,
|
if (map_local(source_pd, utcb,
|
||||||
Obj_crd(remap_src[i], 0),
|
Obj_crd(remap_src[i], 0),
|
||||||
Obj_crd(_sel_exc_base + remap_dst[i], 0)))
|
Obj_crd(_sel_exc_base + remap_dst[i], 0)))
|
||||||
return -6;
|
return -6;
|
||||||
|
@ -87,7 +87,8 @@ void Ram_dataspace_factory::_export_ram_ds(Dataspace_component *ds) {
|
|||||||
Nova::Utcb * const utcb = reinterpret_cast<Nova::Utcb *>(Thread::myself()->utcb());
|
Nova::Utcb * const utcb = reinterpret_cast<Nova::Utcb *>(Thread::myself()->utcb());
|
||||||
const Nova::Rights rights_rw(true, true, false);
|
const Nova::Rights rights_rw(true, true, false);
|
||||||
|
|
||||||
if (map_local(utcb, ds->phys_addr(), reinterpret_cast<addr_t>(virt_ptr),
|
if (map_local(platform_specific()->core_pd_sel(), utcb, ds->phys_addr(),
|
||||||
|
reinterpret_cast<addr_t>(virt_ptr),
|
||||||
page_rounded_size >> get_page_size_log2(), rights_rw, true)) {
|
page_rounded_size >> get_page_size_log2(), rights_rw, true)) {
|
||||||
platform()->region_alloc()->free(virt_ptr, page_rounded_size);
|
platform()->region_alloc()->free(virt_ptr, page_rounded_size);
|
||||||
throw Core_virtual_memory_exhausted();
|
throw Core_virtual_memory_exhausted();
|
||||||
|
@ -114,7 +114,8 @@ void Thread::start()
|
|||||||
utcb_obj->crd_rcv = Obj_crd();
|
utcb_obj->crd_rcv = Obj_crd();
|
||||||
utcb_obj->crd_xlt = Obj_crd();
|
utcb_obj->crd_xlt = Obj_crd();
|
||||||
|
|
||||||
if (map_local(reinterpret_cast<Nova::Utcb *>(Thread::myself()->utcb()),
|
if (map_local(platform_specific()->core_pd_sel(),
|
||||||
|
reinterpret_cast<Nova::Utcb *>(Thread::myself()->utcb()),
|
||||||
Obj_crd(PT_SEL_PAGE_FAULT, 0),
|
Obj_crd(PT_SEL_PAGE_FAULT, 0),
|
||||||
Obj_crd(native_thread().exc_pt_sel + PT_SEL_PAGE_FAULT, 0))) {
|
Obj_crd(native_thread().exc_pt_sel + PT_SEL_PAGE_FAULT, 0))) {
|
||||||
error("could not create page fault portal");
|
error("could not create page fault portal");
|
||||||
|
Loading…
Reference in New Issue
Block a user