mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-22 04:52:56 +01:00
Compare commits
281 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e33efde69 | ||
|
|
99a2511496 | ||
|
|
36608b3402 | ||
|
|
00f4ff37f6 | ||
|
|
64d60bbc7f | ||
|
|
aa1082bed7 | ||
|
|
0312bea38b | ||
|
|
0ca1606f10 | ||
|
|
6a1d07de86 | ||
|
|
66957c8113 | ||
|
|
4c45f3451c | ||
|
|
57fdce0465 | ||
|
|
1498bb740b | ||
|
|
93605c2b15 | ||
|
|
ca0d79010d | ||
|
|
148b8efe8e | ||
|
|
7fd53b52df | ||
|
|
1295d5e062 | ||
|
|
e90c77da89 | ||
|
|
f407bc4cbb | ||
|
|
e7f370f779 | ||
|
|
99ec536c53 | ||
|
|
379c6c1cd4 | ||
|
|
bf06b7e360 | ||
|
|
a7dd2b3171 | ||
|
|
43c73eff13 | ||
|
|
b4612d24ce | ||
|
|
961bd41b05 | ||
|
|
d8c2a908b8 | ||
|
|
2e6f281cf0 | ||
|
|
28c6763a7d | ||
|
|
d1b0af5eb9 | ||
|
|
737a3290d9 | ||
|
|
f69b206593 | ||
|
|
dd95266235 | ||
|
|
39a7ffd233 | ||
|
|
fa23c0bd4f | ||
|
|
8c7cadde5f | ||
|
|
491817c00c | ||
|
|
fcd76d10dd | ||
|
|
a11a17147f | ||
|
|
5d9b563503 | ||
|
|
75366c66a4 | ||
|
|
db2fe17269 | ||
|
|
16bc2bc840 | ||
|
|
9a971a500d | ||
|
|
e02d643420 | ||
|
|
4aef209c8b | ||
|
|
a282617407 | ||
|
|
829961b0ad | ||
|
|
7998fdaf3f | ||
|
|
8f1e8c122f | ||
|
|
7bc49b05d0 | ||
|
|
53c6675500 | ||
|
|
9f5c13564c | ||
|
|
3b69dc2a58 | ||
|
|
14a636f9a7 | ||
|
|
46374a6932 | ||
|
|
dd974f00f7 | ||
|
|
9251b1ede8 | ||
|
|
ce27985b8a | ||
|
|
2e04cc2d87 | ||
|
|
1b1693e6ff | ||
|
|
b7575319bf | ||
|
|
1c4c4d6961 | ||
|
|
49ee13168b | ||
|
|
21f031371f | ||
|
|
53c4aa6d22 | ||
|
|
1e8f1b7a5b | ||
|
|
1ac034d16d | ||
|
|
f74c70ec05 | ||
|
|
929a2387d1 | ||
|
|
4f0a75b0bc | ||
|
|
016c3a8d9e | ||
|
|
13b1aab044 | ||
|
|
6a2546d7e9 | ||
|
|
724efcb00c | ||
|
|
bd52e49698 | ||
|
|
8d21064b5e | ||
|
|
324af5d769 | ||
|
|
6e2b7c2b92 | ||
|
|
a100b37fdf | ||
|
|
3893dae673 | ||
|
|
e45f929eca | ||
|
|
433a216919 | ||
|
|
df066521a5 | ||
|
|
6ca8a41232 | ||
|
|
30bfc63b63 | ||
|
|
746011ee28 | ||
|
|
aa4f11905a | ||
|
|
f447fbe1a5 | ||
|
|
481a8ede5f | ||
|
|
14718401ea | ||
|
|
0056167157 | ||
|
|
4a61d008be | ||
|
|
5a6253eeff | ||
|
|
83b0cdf709 | ||
|
|
523791b361 | ||
|
|
020edd3032 | ||
|
|
9c1563be67 | ||
|
|
0b64328944 | ||
|
|
ba8e61653f | ||
|
|
cfd4310684 | ||
|
|
c2af646ad8 | ||
|
|
f7149623ca | ||
|
|
276a1775f1 | ||
|
|
c265cfa593 | ||
|
|
638a9cfd40 | ||
|
|
31fc7c35e2 | ||
|
|
69785504c7 | ||
|
|
c30415fb9b | ||
|
|
46eebede26 | ||
|
|
718b0c0b67 | ||
|
|
676c3830f9 | ||
|
|
e2d9b31bfe | ||
|
|
9947c3d33b | ||
|
|
6f9e15aff8 | ||
|
|
cdb5030cbb | ||
|
|
bdec3dd668 | ||
|
|
e79044d16a | ||
|
|
e68eadf57b | ||
|
|
a9747825fc | ||
|
|
901b3e2bb4 | ||
|
|
eeb2d95b1f | ||
|
|
ca513113f6 | ||
|
|
0bc012eb79 | ||
|
|
41d5959ae5 | ||
|
|
9c9f67d0d6 | ||
|
|
7008013625 | ||
|
|
4b420f6e71 | ||
|
|
a19d491fbd | ||
|
|
f91b1b6258 | ||
|
|
40aa553fa9 | ||
|
|
27ff408985 | ||
|
|
7876dfcb5e | ||
|
|
c888ff0d76 | ||
|
|
aa02fb8256 | ||
|
|
3234e4f775 | ||
|
|
32f6d75cdb | ||
|
|
b803375863 | ||
|
|
ddc79d5563 | ||
|
|
5447c406e5 | ||
|
|
66c5887bd3 | ||
|
|
1645587b6a | ||
|
|
8ed2e150a4 | ||
|
|
4ac81ad179 | ||
|
|
7e517179c9 | ||
|
|
6ec36350d6 | ||
|
|
99979e09ed | ||
|
|
a60966150e | ||
|
|
7c23d6cd81 | ||
|
|
2a576da2b0 | ||
|
|
f32a97da38 | ||
|
|
9cb603eb5f | ||
|
|
332aeba844 | ||
|
|
bdfbe9f20e | ||
|
|
759e11f9af | ||
|
|
b6f59fb9be | ||
|
|
865f2b263f | ||
|
|
3394be9464 | ||
|
|
8c8d53777f | ||
|
|
765053ea94 | ||
|
|
0063f217ca | ||
|
|
e809192b97 | ||
|
|
99ddd1cd85 | ||
|
|
35bfc34db5 | ||
|
|
6efac7672f | ||
|
|
8ca0f04ba0 | ||
|
|
64a9a53c98 | ||
|
|
4f9be09643 | ||
|
|
5df654ace4 | ||
|
|
cca2dbc400 | ||
|
|
a3e30cc96c | ||
|
|
6a076ff621 | ||
|
|
2e99c19601 | ||
|
|
6e15d966c7 | ||
|
|
c4c43ffc9d | ||
|
|
25b41e9cff | ||
|
|
041dd2a133 | ||
|
|
fe45cc8c05 | ||
|
|
68608bb62d | ||
|
|
6a19b30795 | ||
|
|
23ce0b2071 | ||
|
|
65291902e0 | ||
|
|
bf57a5d79c | ||
|
|
07b355b4e4 | ||
|
|
efd20a7ded | ||
|
|
cbd3d0a878 | ||
|
|
880930cb4f | ||
|
|
12f560dc0e | ||
|
|
b6626607f0 | ||
|
|
feedbe4bb9 | ||
|
|
c8cf882a94 | ||
|
|
89403a24b3 | ||
|
|
2e6255d1cf | ||
|
|
f71e38702f | ||
|
|
e1370b558e | ||
|
|
1c67e3bb43 | ||
|
|
944be1b4e6 | ||
|
|
22c1f8772b | ||
|
|
b893968232 | ||
|
|
b8beba5bf3 | ||
|
|
1aadce4496 | ||
|
|
49eeb485d9 | ||
|
|
906b4dc90a | ||
|
|
f4bd2368f6 | ||
|
|
8eef91f2ac | ||
|
|
1c8c30e1f4 | ||
|
|
2bdf0e70e9 | ||
|
|
3bdf70f771 | ||
|
|
750f5313f7 | ||
|
|
a596bfe797 | ||
|
|
6aa0ab1bf9 | ||
|
|
42f51cd802 | ||
|
|
4009619206 | ||
|
|
77130a9404 | ||
|
|
212fc47768 | ||
|
|
ea9c0e20ba | ||
|
|
af86e33c3f | ||
|
|
35bb156972 | ||
|
|
e73a71be12 | ||
|
|
56a7d00a44 | ||
|
|
b10b9e20a2 | ||
|
|
1bc16f3a23 | ||
|
|
038fcf032a | ||
|
|
cc3b1599b8 | ||
|
|
1f75805d54 | ||
|
|
50c30b1702 | ||
|
|
05ad5a6ad4 | ||
|
|
9759000538 | ||
|
|
776fdceaa5 | ||
|
|
eaed3ba207 | ||
|
|
b24f48b125 | ||
|
|
8b7c67976d | ||
|
|
277ca33988 | ||
|
|
c3c643bcf1 | ||
|
|
9c698ab6c1 | ||
|
|
7b49dbf2f3 | ||
|
|
9b456fb3be | ||
|
|
4519b39ba7 | ||
|
|
c4068c4001 | ||
|
|
d57319bbcb | ||
|
|
576b9389cb | ||
|
|
1ba4e033a7 | ||
|
|
c05a80a139 | ||
|
|
9d82720a29 | ||
|
|
020ba97106 | ||
|
|
adc63ef2a6 | ||
|
|
66d499e416 | ||
|
|
bf90fd5f66 | ||
|
|
fec51620f7 | ||
|
|
1b7b0b2050 | ||
|
|
4c74af274b | ||
|
|
1256b01867 | ||
|
|
0c8a4f9f3a | ||
|
|
5a4cb7fcfb | ||
|
|
f4c724639b | ||
|
|
8514eecc90 | ||
|
|
51db6a6056 | ||
|
|
a2e6fdd922 | ||
|
|
31b4062688 | ||
|
|
f356ad2bdf | ||
|
|
e35d7c979f | ||
|
|
16d48eaf1e | ||
|
|
da116c66ba | ||
|
|
8d19aad601 | ||
|
|
6e90f70ec2 | ||
|
|
b5922fb7f1 | ||
|
|
1eeb68bf56 | ||
|
|
aca62c7180 | ||
|
|
fd003f0e00 | ||
|
|
54610247ad | ||
|
|
2b8e5d7b19 | ||
|
|
5e3d505ef4 | ||
|
|
dc8cbbf022 | ||
|
|
4359b99c4f | ||
|
|
575a81a633 | ||
|
|
f128a52e8b | ||
|
|
d46b30a711 | ||
|
|
fbeaa9e358 | ||
|
|
aa220ba042 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -17,6 +17,8 @@
|
||||
/dde_linux/download
|
||||
/dde_oss/contrib
|
||||
/dde_oss/download
|
||||
/dde_rump/contrib
|
||||
/dde_rump/include/rump
|
||||
/libports/contrib
|
||||
/libports/download
|
||||
/libports/include/curl/
|
||||
|
||||
7
README
7
README
@@ -152,6 +152,13 @@ The Genode source tree is composed of the following subdirectories:
|
||||
This source-code repository contains the device-driver environment for the
|
||||
audio drivers of the Open Sound System (OSS).
|
||||
|
||||
:'dde_rump':
|
||||
|
||||
This source-code repository contains the port of rump kernels, which are
|
||||
used to execute subsystems of the NetBSD kernel as user level processes.
|
||||
The repository contains a server that uses a rump kernel to provide
|
||||
various NetBSD file systems to Genode.
|
||||
|
||||
:'qt4':
|
||||
|
||||
This source-code repository contains the Genode version of Qt4 framework.
|
||||
|
||||
@@ -95,13 +95,15 @@ namespace Genode {
|
||||
/**
|
||||
* Thread-context area configuration.
|
||||
*/
|
||||
static addr_t context_area_virtual_base() { return 0x40000000UL; }
|
||||
static addr_t context_area_virtual_size() { return 0x10000000UL; }
|
||||
static constexpr addr_t context_area_virtual_base() {
|
||||
return 0x40000000UL; }
|
||||
static constexpr addr_t context_area_virtual_size() {
|
||||
return 0x10000000UL; }
|
||||
|
||||
/**
|
||||
* Size of virtual address region holding the context of one thread
|
||||
*/
|
||||
static addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
};
|
||||
|
||||
struct Native_pd_args { };
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
# \date 2013-02-14
|
||||
#
|
||||
|
||||
LIBS += cxx l4 startup
|
||||
LIBS += cxx syscall startup
|
||||
|
||||
SRC_CC += cap_copy.cc main_bootstrap.cc
|
||||
SRC_CC += cap_copy.cc
|
||||
SRC_CC += ipc/ipc.cc ipc/pager.cc ipc/ipc_marshal_cap.cc
|
||||
SRC_CC += pager/pager.cc pager/common.cc
|
||||
SRC_CC += avl_tree/avl_tree.cc
|
||||
@@ -21,14 +21,13 @@ SRC_CC += lock/lock.cc
|
||||
SRC_CC += signal/signal.cc signal/common.cc
|
||||
SRC_CC += server/server.cc server/common.cc
|
||||
SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc
|
||||
SRC_CC += env/utcb.cc
|
||||
SRC_CC += thread/context_allocator.cc env/utcb.cc
|
||||
SRC_CC += lock/cmpxchg.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/thread
|
||||
INC_DIR += $(REP_DIR)/include/codezero/dummies
|
||||
|
||||
vpath main_bootstrap.cc $(REP_DIR)/src/platform
|
||||
vpath cap_copy.cc $(BASE_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
vpath cap_copy.cc $(BASE_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
SRC_CC += console/log_console.cc
|
||||
SRC_CC += env/env.cc env/context_area.cc env/reload_parent_cap.cc
|
||||
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
|
||||
SRC_CC += thread/thread_start.cc
|
||||
|
||||
INC_DIR += $(BASE_DIR)/src/base/env
|
||||
|
||||
@@ -7,7 +7,7 @@ index 7b315b8..ace38d8 100644
|
||||
struct container;
|
||||
|
||||
-#define tcb_pagerid(tcb) ((tcb)->pager->tid)
|
||||
+#define tcb_pagerid(tcb) 3
|
||||
+#define tcb_pagerid(tcb) 4
|
||||
|
||||
#define space_is_pager(tcb) \
|
||||
((tcb)->space->spid == (tcb)->pager->space->spid)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Thread bootstrap code
|
||||
* \author Christian Prochaska
|
||||
* \author Martin Stein
|
||||
* \date 2013-02-15
|
||||
*/
|
||||
|
||||
@@ -13,13 +14,83 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/env.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
Genode::Native_thread_id main_thread_tid;
|
||||
Codezero::l4_mutex main_thread_running_lock;
|
||||
|
||||
|
||||
/*****************************
|
||||
** Startup library support **
|
||||
*****************************/
|
||||
|
||||
void prepare_init_main_thread()
|
||||
{
|
||||
/* initialize codezero environment */
|
||||
Codezero::__l4_init();
|
||||
|
||||
/* provide kernel identification of thread through temporary environment */
|
||||
main_thread_tid = Codezero::thread_myself();
|
||||
}
|
||||
|
||||
void prepare_reinit_main_thread() { prepare_init_main_thread(); }
|
||||
|
||||
|
||||
/****************************
|
||||
** Codezero libl4 support **
|
||||
****************************/
|
||||
|
||||
/*
|
||||
* Unfortunately, the function 'exregs_print_registers' in 'exregs.c' refers to
|
||||
* 'memset'. Because we do not want to link core against a C library, we have to
|
||||
* resolve this function here.
|
||||
*/
|
||||
extern "C" void *memset(void *s, int c, Genode::size_t n) __attribute__((weak));
|
||||
extern "C" void *memset(void *s, int c, Genode::size_t n)
|
||||
{
|
||||
return Genode::memset(s, c, n);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Same problem as for 'memset'. The 'printf' symbol is referenced from
|
||||
* 'mutex.c' and 'exregs.c' of Codezero's libl4.
|
||||
*/
|
||||
extern "C" int printf(const char *format, ...) __attribute__((weak));
|
||||
extern "C" int printf(const char *format, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
Genode::vprintf(format, list);
|
||||
va_end(list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
void Genode::Thread_base::_thread_bootstrap()
|
||||
{
|
||||
Codezero::l4_mutex_init(utcb()->running_lock());
|
||||
Codezero::l4_mutex_lock(utcb()->running_lock()); /* block on first mutex lock */
|
||||
}
|
||||
|
||||
|
||||
void Genode::Thread_base::_init_platform_thread(Type type)
|
||||
{
|
||||
if (type == NORMAL) { return; }
|
||||
|
||||
/* adjust values whose computation differs for a main thread */
|
||||
_tid.l4id = main_thread_tid;
|
||||
_thread_cap = Genode::env()->parent()->main_thread_cap();
|
||||
|
||||
/* get first mutex lock (normally done by _thread_bootstrap) */
|
||||
Codezero::l4_mutex_init(utcb()->running_lock());
|
||||
Codezero::l4_mutex_lock(utcb()->running_lock());
|
||||
}
|
||||
|
||||
@@ -39,9 +39,6 @@ void Thread_base::_thread_start()
|
||||
** Thread base **
|
||||
*****************/
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
env()->cpu_session()->kill_thread(_thread_cap);
|
||||
@@ -64,9 +61,7 @@ void Thread_base::start()
|
||||
env()->cpu_session()->set_pager(_thread_cap, _pager_cap);
|
||||
|
||||
/* register initial IP and SP at core */
|
||||
addr_t thread_sp = (addr_t)&_context->stack[-4];
|
||||
thread_sp &= ~0xf; /* align initial stack to 16 byte boundary */
|
||||
env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, thread_sp);
|
||||
env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, _context->stack_top());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,10 +27,6 @@ enum { verbose_thread_start = true };
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread() { }
|
||||
|
||||
|
||||
@@ -104,7 +100,7 @@ void Thread_base::start()
|
||||
/* create and start platform thread */
|
||||
_tid.pt = new(platform()->core_mem_alloc()) Platform_thread(_context->name);
|
||||
|
||||
_tid.l4id = create_thread(1, &_context->stack[-4], (void *)&_thread_start);
|
||||
_tid.l4id = create_thread(1, stack_top(), (void *)&_thread_start);
|
||||
|
||||
if (_tid.l4id < 0)
|
||||
PERR("create_thread returned %d", _tid.l4id);
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* \brief Platform-specific helper functions for the _main() function
|
||||
* \author Norman Feske
|
||||
* \author Christian Helmuth
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/thread.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
|
||||
/****************************
|
||||
** Codezero libl4 support **
|
||||
****************************/
|
||||
|
||||
/*
|
||||
* Unfortunately, the function 'exregs_print_registers' in 'exregs.c' refers to
|
||||
* 'memset'. Because we do not want to link core against a C library, we have to
|
||||
* resolve this function here.
|
||||
*/
|
||||
extern "C" void *memset(void *s, int c, Genode::size_t n) __attribute__((weak));
|
||||
extern "C" void *memset(void *s, int c, Genode::size_t n)
|
||||
{
|
||||
return Genode::memset(s, c, n);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Same problem as for 'memset'. The 'printf' symbol is referenced from
|
||||
* 'mutex.c' and 'exregs.c' of Codezero's libl4.
|
||||
*/
|
||||
extern "C" int printf(const char *format, ...) __attribute__((weak));
|
||||
extern "C" int printf(const char *format, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
Genode::vprintf(format, list);
|
||||
va_end(list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**************************
|
||||
** Startup-code helpers **
|
||||
**************************/
|
||||
|
||||
namespace Genode { void platform_main_bootstrap(); }
|
||||
|
||||
|
||||
Genode::Native_thread_id main_thread_tid;
|
||||
Codezero::l4_mutex main_thread_running_lock;
|
||||
|
||||
|
||||
void Genode::platform_main_bootstrap()
|
||||
{
|
||||
static struct Bootstrap
|
||||
{
|
||||
Bootstrap()
|
||||
{
|
||||
Codezero::__l4_init();
|
||||
|
||||
main_thread_tid = Codezero::thread_myself();
|
||||
|
||||
Codezero::l4_mutex_init(&main_thread_running_lock);
|
||||
Codezero::l4_mutex_lock(&main_thread_running_lock); /* block on first mutex lock */
|
||||
}
|
||||
} bootstrap;
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* \brief Atomic operations for ARM
|
||||
* \author Norman Feske
|
||||
* \date 2007-04-28
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__ARM__CPU__ATOMIC_H_
|
||||
#define _INCLUDE__ARM__CPU__ATOMIC_H_
|
||||
|
||||
namespace Genode {
|
||||
|
||||
extern "C" long int
|
||||
l4_atomic_cmpxchg(volatile long int*, long int, long int);
|
||||
|
||||
/**
|
||||
* Atomic compare and exchange
|
||||
*
|
||||
* This function compares the value at dest with cmp_val.
|
||||
* If both values are equal, dest is set to new_val. If
|
||||
* both values are different, the value at dest remains
|
||||
* unchanged.
|
||||
*
|
||||
* \return 1 if the value was successfully changed to new_val,
|
||||
* 0 if cmp_val and the value at dest differ.
|
||||
*/
|
||||
inline int cmpxchg(volatile int *dest, int cmp_val, int new_val)
|
||||
{
|
||||
return l4_atomic_cmpxchg((volatile long int *)dest, cmp_val, new_val);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__ARM__CPU__ATOMIC_H_ */
|
||||
@@ -78,13 +78,15 @@ namespace Genode {
|
||||
/**
|
||||
* Thread-context area configuration.
|
||||
*/
|
||||
static addr_t context_area_virtual_base() { return 0x40000000UL; }
|
||||
static addr_t context_area_virtual_size() { return 0x10000000UL; }
|
||||
static constexpr addr_t context_area_virtual_base() {
|
||||
return 0x40000000UL; }
|
||||
static constexpr addr_t context_area_virtual_size() {
|
||||
return 0x10000000UL; }
|
||||
|
||||
/**
|
||||
* Size of virtual address region holding the context of one thread
|
||||
*/
|
||||
static addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
};
|
||||
|
||||
struct Native_pd_args { };
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#
|
||||
# Configuration for L4 build system (for kernel-bindings, sigma0, bootstrap).
|
||||
#
|
||||
L4_CONFIG = $(REP_DIR)/config/l4env-config.x86
|
||||
|
||||
include $(REP_DIR)/lib/mk/platform.inc
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
LIBS += cxx startup
|
||||
|
||||
SRC_CC += cap_copy.cc main_bootstrap.cc
|
||||
SRC_CC += cap_copy.cc
|
||||
SRC_CC += ipc/ipc.cc ipc/pager.cc ipc/ipc_marshal_cap.cc
|
||||
SRC_CC += pager/pager.cc pager/common.cc
|
||||
SRC_CC += avl_tree/avl_tree.cc
|
||||
@@ -20,12 +20,12 @@ SRC_CC += elf/elf_binary.cc
|
||||
SRC_CC += lock/lock.cc
|
||||
SRC_CC += signal/signal.cc signal/common.cc
|
||||
SRC_CC += server/server.cc server/common.cc
|
||||
SRC_CC += thread/thread.cc thread/thread_bootstrap_empty.cc thread/trace.cc
|
||||
SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc
|
||||
SRC_CC += thread/context_allocator.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/thread
|
||||
|
||||
vpath main_bootstrap.cc $(REP_DIR)/src/platform
|
||||
vpath cap_copy.cc $(BASE_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
vpath cap_copy.cc $(BASE_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
LIBS += base-common
|
||||
|
||||
SRC_CC += console/log_console.cc
|
||||
SRC_CC += env/env.cc env/context_area.cc env/reload_parent_cap.cc
|
||||
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
|
||||
SRC_CC += thread/thread_start.cc
|
||||
|
||||
INC_DIR += $(BASE_DIR)/src/base/env
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
#
|
||||
# Specifics for Fiasco on ARM
|
||||
#
|
||||
# The following variables must be defined by a platform spec file:
|
||||
#
|
||||
# L4SYS_ARM_CPU - Platform identifiert used for constructing l4sys path
|
||||
# names corresponding to the ARM platform. For example,
|
||||
# specify 'arm_int' for the ARM integrator board.
|
||||
# RAM_BASE - Start address of physical memory. If not specified,
|
||||
# the start adress 0x0 is used.
|
||||
#
|
||||
|
||||
SPECS += arm fiasco 32bit
|
||||
|
||||
#
|
||||
# ARM-specific L4/sys headers
|
||||
#
|
||||
L4_INC_DIR += $(L4_BUILD_DIR)/include/arm/l4v2 \
|
||||
$(L4_BUILD_DIR)/include/arm
|
||||
|
||||
#
|
||||
# Support for Fiasco's ARM-specific extensions of L4
|
||||
# and ARM-specific utility functions.
|
||||
#
|
||||
REP_INC_DIR += include/arm
|
||||
|
||||
#
|
||||
# Defines for L4/sys headers
|
||||
#
|
||||
CC_OPT += -DSYSTEM_$(L4SYS_ARM_CPU)_l4v2
|
||||
CC_OPT += -DCONFIG_L4_CALL_SYSCALLS -DL4API_l4v2 -DARCH_arm
|
||||
CC_OPT += -msoft-float -fomit-frame-pointer
|
||||
AS_OPT += -mfpu=softfpa
|
||||
|
||||
#
|
||||
# Linker options that are specific for L4 on ARM
|
||||
#
|
||||
RAM_BASE ?= 0x0
|
||||
LD_TEXT_ADDR ?= $(shell printf "0x%x" $$(($(RAM_BASE) + 0x00078000)))
|
||||
CXX_LINK_OPT += -Wl,-Ttext=$(LINK_TEXT_ADDR)
|
||||
CXX_LINK_OPT += -L$(L4_BUILD_DIR)/lib/$(L4SYS_ARM_CPU)/l4v2
|
||||
EXT_OBJECTS += -ll4sys
|
||||
|
||||
#
|
||||
# Also include less-specific configuration last
|
||||
#
|
||||
include $(call select_from_repositories,mk/spec-32bit.mk)
|
||||
include $(call select_from_repositories,mk/spec-fiasco.mk)
|
||||
|
||||
INC_DIR += $(L4_INC_DIR)
|
||||
41
base-fiasco/src/base/thread/thread_bootstrap.cc
Normal file
41
base-fiasco/src/base/thread/thread_bootstrap.cc
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* \brief Platform specific thread initialization
|
||||
* \author Martin Stein
|
||||
* \date 2014-01-06
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/env.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/*****************************
|
||||
** Startup library support **
|
||||
*****************************/
|
||||
|
||||
void prepare_init_main_thread() { }
|
||||
|
||||
void prepare_reinit_main_thread() { }
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
void Thread_base::_thread_bootstrap() { }
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread(Type type)
|
||||
{
|
||||
if (type == NORMAL) { return; }
|
||||
_thread_cap = Genode::env()->parent()->main_thread_cap();
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* \brief Platform support specific to ARM
|
||||
* \author Norman Feske
|
||||
* \date 2007-10-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
void Platform::_setup_io_port_alloc()
|
||||
{
|
||||
/*
|
||||
* This is just a dummy init function for the I/O port allocator.
|
||||
* ARM does not I/O port support.
|
||||
*/
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
include $(PRG_DIR)/../target.inc
|
||||
|
||||
REQUIRES += arm
|
||||
SRC_CC += platform_arm.cc
|
||||
|
||||
vpath io_port_session_component.cc $(GEN_CORE_DIR)/arm
|
||||
vpath platform_services.cc $(GEN_CORE_DIR)
|
||||
|
||||
@@ -41,7 +41,7 @@ void Thread_base::start()
|
||||
_tid.pt->pager(platform_specific()->core_pager());
|
||||
_tid.l4id = _tid.pt->native_thread_id();
|
||||
|
||||
_tid.pt->start((void *)_thread_start, _context->stack);
|
||||
_tid.pt->start((void *)_thread_start, stack_top());
|
||||
}
|
||||
|
||||
|
||||
@@ -53,9 +53,6 @@ void Thread_base::cancel_blocking()
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
/* destruct platform thread */
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
SRC = ../x86/genode.ld
|
||||
TARGET = genode.ld
|
||||
|
||||
all:
|
||||
@echo "--- available targets ---"
|
||||
@echo " genode.ld - generate $(TARGET) from $(SRC)"
|
||||
@echo " cleanall - remove generated file"
|
||||
|
||||
#
|
||||
# NOTE: We change the start address to 0x60000, which
|
||||
# is the same address as used by the original
|
||||
# roottask.
|
||||
#
|
||||
# On L4x0, the thread ID type is only 32bit instead of 64bit
|
||||
# for L4v2. Therefore, we have to adapt the place holder for
|
||||
# thread ID part of the parent capability.
|
||||
#
|
||||
genode.ld:
|
||||
cp $(SRC) $@
|
||||
sed -i "s/= 0x[0-9]\+;/= 0x00060000;/" $@
|
||||
sed -i "54s/^.*$$/\t\tLONG(0xffffffff);/" $@
|
||||
|
||||
clean cleanall:
|
||||
rm -f $(TARGET)
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
/**
|
||||
* \brief Startup code for Fiasco/ARM
|
||||
* \author Norman Feske
|
||||
* \date 2007-04-30
|
||||
*
|
||||
* Call constructors for static objects before calling main().
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
namespace Fiasco {
|
||||
#include <l4/sys/kdebug.h>
|
||||
}
|
||||
|
||||
/* Genode */
|
||||
#include <base/crt0.h>
|
||||
#include <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* Return constructed parent capability
|
||||
*/
|
||||
Parent_capability parent_cap()
|
||||
{
|
||||
Fiasco::l4_threadid_t tid = *(Fiasco::l4_threadid_t *)&_parent_cap_thread_id;
|
||||
return Parent_capability(Native_capability(tid, _parent_cap_local_name));
|
||||
}
|
||||
}
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/***************
|
||||
** C++ stuff **
|
||||
***************/
|
||||
|
||||
/*
|
||||
* This symbol must be defined when exception
|
||||
* headers are defined in the linker script.
|
||||
*/
|
||||
extern "C" __attribute__((weak)) void *__gxx_personality_v0(void)
|
||||
{
|
||||
Fiasco::outstring("What a surprise! This function is really used? Sorry - not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resolve symbols needed by libsupc++ to make
|
||||
* the linker happy.
|
||||
*
|
||||
* FIXME: implement us!
|
||||
*/
|
||||
extern "C" __attribute__((weak)) int atexit(void) {
|
||||
Fiasco::outstring("atexit() called - not implemented!\n");
|
||||
return 0;
|
||||
};
|
||||
extern "C" __attribute__((weak)) int memcmp(void) {
|
||||
Fiasco::outstring("memcmp() called - not implemented!\n");
|
||||
return 0;
|
||||
};
|
||||
extern "C" __attribute__((weak)) int strncmp(void) {
|
||||
Fiasco::outstring("strncmp() called - not implemented!\n");
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
extern int main(int argc, char **argv);
|
||||
|
||||
extern void init_exception_handling(); /* implemented in base/cxx */
|
||||
|
||||
|
||||
/* FIXME no support for commandline
|
||||
* ask parent for argc and argv */
|
||||
static char argv0[] = { '_', 'm', 'a', 'i', 'n'};
|
||||
static char *argv[1] = { argv0 };
|
||||
|
||||
|
||||
/*
|
||||
* Define 'environ' pointer that is supposed to be exported by
|
||||
* the startup code and relied on by any libC. Because we have no
|
||||
* UNIX environment, however, we set this pointer to NULL.
|
||||
*/
|
||||
__attribute__((weak)) char **environ = (char **)0;
|
||||
|
||||
|
||||
/**
|
||||
* C entry function called by the crt0 startup code
|
||||
*/
|
||||
extern "C" int _main()
|
||||
{
|
||||
/* call constructors for static objects */
|
||||
void (**func)();
|
||||
for (func = &_ctors_end; func != &_ctors_start; (*--func)());
|
||||
|
||||
/* initialize exception handling */
|
||||
init_exception_handling();
|
||||
|
||||
/* completely map program image by touching all pages read-only */
|
||||
volatile const char *beg, *end;
|
||||
beg = (const char *)(((unsigned)&_prog_img_beg) & L4_PAGEMASK);
|
||||
end = (const char *)&_prog_img_end;
|
||||
for ( ; beg < end; beg += L4_PAGESIZE) (void)(*beg);
|
||||
|
||||
/* call real main function */
|
||||
/* XXX no support for commandline */
|
||||
int ret = main(1, argv);
|
||||
|
||||
/* inform parent about program exit */
|
||||
env()->parent()->exit(ret);
|
||||
|
||||
PDBG("main() returned %d", ret);
|
||||
sleep_forever();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/**
|
||||
* \brief Startup code for Genode applications on ARM
|
||||
* \author Norman Feske
|
||||
* \date 2007-04-28
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/*--- .text (program code) -------------------------*/
|
||||
.text
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
|
||||
ldr sp, .initial_sp
|
||||
b _main
|
||||
|
||||
.initial_sp: .word _stack_high
|
||||
|
||||
.globl __dso_handle
|
||||
__dso_handle:
|
||||
.long 0
|
||||
|
||||
/*--- .bss (non-initialized data) ------------------*/
|
||||
.section ".bss"
|
||||
|
||||
.globl _stack_low
|
||||
_stack_low:
|
||||
.space 64*1024
|
||||
.globl _stack_high
|
||||
_stack_high:
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* \brief Platform-specific helper functions for the _main() function
|
||||
* \author Christian Prochaska
|
||||
* \date 2009-08-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
namespace Genode { void platform_main_bootstrap() { /* dummy */ } }
|
||||
38
base-foc/include/arm/base/native_config.h
Normal file
38
base-foc/include/arm/base/native_config.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* \brief Platform-specific context area definitions
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2014-01-24
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__BASE__NATIVE_CONFIG_H_
|
||||
#define _INCLUDE__BASE__NATIVE_CONFIG_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
struct Native_config
|
||||
{
|
||||
/**
|
||||
* Thread-context area configuration
|
||||
*/
|
||||
static constexpr addr_t context_area_virtual_base() {
|
||||
return 0x20000000UL; }
|
||||
static constexpr addr_t context_area_virtual_size() {
|
||||
return 0x10000000UL; }
|
||||
|
||||
/**
|
||||
* Size of virtual address region holding the context of one thread
|
||||
*/
|
||||
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__BASE__NATIVE_CONFIG_H_ */
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <base/cap_map.h>
|
||||
#include <base/native_types.h>
|
||||
#include <util/assert.h>
|
||||
#include <util/construct_at.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
@@ -124,6 +125,11 @@ namespace Genode {
|
||||
|
||||
bool static_idx(Cap_index *idx) {
|
||||
return ((T*)idx) < &_indices[START_IDX]; }
|
||||
|
||||
void reinit()
|
||||
{
|
||||
construct_at<Cap_index_allocator_tpl<T, SZ> >(this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -146,6 +146,11 @@ namespace Genode
|
||||
* \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;
|
||||
};
|
||||
|
||||
|
||||
@@ -196,7 +201,9 @@ namespace Genode
|
||||
* to save entries in the capability space, and prevent leaks of
|
||||
* them.
|
||||
*/
|
||||
class Capability_map : Noncopyable
|
||||
class Capability_map
|
||||
:
|
||||
private Noncopyable
|
||||
{
|
||||
private:
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
|
||||
#define _INCLUDE__BASE__NATIVE_TYPES_H_
|
||||
|
||||
#include <base/native_config.h>
|
||||
#include <base/cap_map.h>
|
||||
#include <base/stdint.h>
|
||||
|
||||
namespace Fiasco {
|
||||
#include <l4/sys/consts.h>
|
||||
@@ -178,20 +178,6 @@ namespace Genode {
|
||||
|
||||
typedef int Native_connection_state;
|
||||
|
||||
struct Native_config
|
||||
{
|
||||
/**
|
||||
* Thread-context area configuration
|
||||
*/
|
||||
static addr_t context_area_virtual_base();
|
||||
static addr_t context_area_virtual_size() { return 0x10000000UL; }
|
||||
|
||||
/**
|
||||
* Size of virtual address region holding the context of one thread
|
||||
*/
|
||||
static addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
};
|
||||
|
||||
struct Native_pd_args { };
|
||||
}
|
||||
|
||||
|
||||
38
base-foc/include/x86/base/native_config.h
Normal file
38
base-foc/include/x86/base/native_config.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* \brief Platform-specific context area definitions
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2014-01-24
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__BASE__NATIVE_CONFIG_H_
|
||||
#define _INCLUDE__BASE__NATIVE_CONFIG_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
struct Native_config
|
||||
{
|
||||
/**
|
||||
* Thread-context area configuration
|
||||
*/
|
||||
static constexpr addr_t context_area_virtual_base() {
|
||||
return 0x40000000UL; }
|
||||
static constexpr addr_t context_area_virtual_size() {
|
||||
return 0x10000000UL; }
|
||||
|
||||
/**
|
||||
* Size of virtual address region holding the context of one thread
|
||||
*/
|
||||
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__BASE__NATIVE_CONFIG_H_ */
|
||||
@@ -1,3 +0,0 @@
|
||||
include $(REP_DIR)/lib/mk/base.inc
|
||||
|
||||
SRC_CC += thread/thread_context_area.cc
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
LIBS += cxx syscall startup
|
||||
|
||||
SRC_CC += main_bootstrap.cc
|
||||
SRC_CC += ipc/ipc.cc ipc/pager.cc
|
||||
SRC_CC += pager/pager.cc pager/common.cc
|
||||
SRC_CC += avl_tree/avl_tree.cc
|
||||
@@ -22,13 +21,13 @@ SRC_CC += env/spin_lock.cc env/cap_map.cc
|
||||
SRC_CC += signal/signal.cc signal/common.cc
|
||||
SRC_CC += server/server.cc server/common.cc
|
||||
SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc
|
||||
SRC_CC += thread/context_allocator.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/thread
|
||||
|
||||
vpath main_bootstrap.cc $(REP_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
|
||||
# vi: set ft=make :
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
LIBS += base-common
|
||||
|
||||
SRC_CC += console/log_console.cc
|
||||
SRC_CC += env/env.cc env/context_area.cc env/reload_parent_cap.cc \
|
||||
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc \
|
||||
env/cap_map_remove.cc env/cap_alloc.cc
|
||||
SRC_CC += thread/thread_start.cc
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
include $(REP_DIR)/lib/mk/base.inc
|
||||
|
||||
SRC_CC += thread/arndale/thread_context_area.cc
|
||||
@@ -1,3 +0,0 @@
|
||||
include $(REP_DIR)/lib/mk/base.inc
|
||||
|
||||
SRC_CC += thread/thread_context_area.cc
|
||||
@@ -1,4 +1,4 @@
|
||||
SPECS += foc_arm platform_arndale uboot
|
||||
SPECS += foc_arm platform_arndale
|
||||
|
||||
include $(call select_from_repositories,mk/spec-fpu_vfpv3.mk)
|
||||
include $(call select_from_repositories,mk/spec-platform_arndale.mk)
|
||||
|
||||
@@ -211,6 +211,7 @@ proc build_boot_image_x86 {binaries} {
|
||||
|
||||
proc build_boot_image_arm {binaries} {
|
||||
|
||||
global run_target
|
||||
global fiasco_serial_esc_arg
|
||||
|
||||
copy_and_strip_binaries $binaries
|
||||
@@ -254,7 +255,7 @@ proc build_boot_image_arm {binaries} {
|
||||
if {[info exists ::env(PXE_TFTP_DIR_BASE)] &&
|
||||
[info exists ::env(PXE_TFTP_DIR_OFFSET)]} {
|
||||
exec ln -sf "[pwd]/[run_dir]/image.elf" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)"
|
||||
if {[have_spec uboot]} {
|
||||
if {[regexp "uboot" $run_target]} {
|
||||
exec ln -sf "[pwd]/[run_dir]/uImage" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)/uImage"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* \brief Arndale specific definition of the context area location
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2013-02-12
|
||||
*
|
||||
* We need to place the context area within core outside the physical memory.
|
||||
* Sigma0 maps physical to core-local memory always 1:1 when using
|
||||
* SIGMA0_REQ_FPAGE_ANY. Those mappings would interfere with the context area.
|
||||
*
|
||||
* Because the UTCB area of a task resides at the end of the context area and
|
||||
* its address gets calculated by core, the context area in other tasks needs
|
||||
* to be at the same address as in core.
|
||||
*/
|
||||
|
||||
#include <base/native_types.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
addr_t Native_config::context_area_virtual_base() { return 0x20000000UL; }
|
||||
@@ -17,10 +17,6 @@
|
||||
#include <util/string.h>
|
||||
#include <util/misc_math.h>
|
||||
|
||||
namespace Fiasco {
|
||||
#include <l4/sys/utcb.h>
|
||||
}
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
@@ -35,77 +31,8 @@ namespace Genode {
|
||||
}
|
||||
|
||||
|
||||
/******************************
|
||||
** Thread-context allocator **
|
||||
******************************/
|
||||
|
||||
Thread_base::Context *Thread_base::Context_allocator::base_to_context(addr_t base)
|
||||
{
|
||||
addr_t result = base + Native_config::context_virtual_size() - sizeof(Context);
|
||||
return reinterpret_cast<Context *>(result);
|
||||
}
|
||||
|
||||
|
||||
addr_t Thread_base::Context_allocator::addr_to_base(void *addr)
|
||||
{
|
||||
return ((addr_t)addr) & ~(Native_config::context_virtual_size() - 1);
|
||||
}
|
||||
|
||||
|
||||
bool Thread_base::Context_allocator::_is_in_use(addr_t base)
|
||||
{
|
||||
List_element<Thread_base> *le = _threads.first();
|
||||
for (; le; le = le->next())
|
||||
if (base_to_context(base) == le->object()->_context)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Context *Thread_base::Context_allocator::alloc(Thread_base *thread_base)
|
||||
{
|
||||
Lock::Guard _lock_guard(_threads_lock);
|
||||
|
||||
/*
|
||||
* Find slot in context area for the new context
|
||||
*/
|
||||
addr_t base = Native_config::context_area_virtual_base();
|
||||
for (; _is_in_use(base); base += Native_config::context_virtual_size()) {
|
||||
|
||||
/* check upper bound of context area */
|
||||
if (base >= Native_config::context_area_virtual_base() + Native_config::context_area_virtual_size())
|
||||
return 0;
|
||||
}
|
||||
|
||||
_threads.insert(&thread_base->_list_element);
|
||||
|
||||
return base_to_context(base);
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::Context_allocator::free(Thread_base *thread_base)
|
||||
{
|
||||
Lock::Guard _lock_guard(_threads_lock);
|
||||
|
||||
_threads.remove(&thread_base->_list_element);
|
||||
|
||||
thread_base->_context->~Context();
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread base **
|
||||
*****************/
|
||||
|
||||
Thread_base::Context_allocator *Thread_base::_context_allocator()
|
||||
{
|
||||
static Context_allocator context_allocator_inst;
|
||||
return &context_allocator_inst;
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Context *Thread_base::_alloc_context(size_t stack_size)
|
||||
Thread_base::Context *
|
||||
Thread_base::_alloc_context(size_t stack_size, bool main_thread)
|
||||
{
|
||||
/*
|
||||
* Synchronize context list when creating new threads from multiple threads
|
||||
@@ -116,7 +43,7 @@ Thread_base::Context *Thread_base::_alloc_context(size_t stack_size)
|
||||
Lock::Guard _lock_guard(alloc_lock);
|
||||
|
||||
/* allocate thread context */
|
||||
Context *context = _context_allocator()->alloc(this);
|
||||
Context *context = _context_allocator()->alloc(this, main_thread);
|
||||
if (!context)
|
||||
throw Context_alloc_failed();
|
||||
|
||||
@@ -124,7 +51,8 @@ Thread_base::Context *Thread_base::_alloc_context(size_t stack_size)
|
||||
enum { PAGE_SIZE_LOG2 = 12 };
|
||||
size_t ds_size = align_addr(stack_size, PAGE_SIZE_LOG2);
|
||||
|
||||
if (stack_size >= Native_config::context_virtual_size() - sizeof(Native_utcb) - (1 << PAGE_SIZE_LOG2))
|
||||
if (stack_size >= Native_config::context_virtual_size() -
|
||||
sizeof(Native_utcb) - (1UL << PAGE_SIZE_LOG2))
|
||||
throw Stack_too_large();
|
||||
|
||||
/*
|
||||
@@ -132,8 +60,9 @@ Thread_base::Context *Thread_base::_alloc_context(size_t stack_size)
|
||||
*
|
||||
* The stack is always located at the top of the context.
|
||||
*/
|
||||
addr_t ds_addr = Context_allocator::addr_to_base(context) + Native_config::context_virtual_size()
|
||||
- ds_size;
|
||||
addr_t ds_addr = Context_allocator::addr_to_base(context) +
|
||||
Native_config::context_virtual_size() -
|
||||
ds_size;
|
||||
|
||||
/* add padding for UTCB if defined for the platform */
|
||||
if (sizeof(Native_utcb) >= (1 << PAGE_SIZE_LOG2))
|
||||
@@ -144,41 +73,53 @@ Thread_base::Context *Thread_base::_alloc_context(size_t stack_size)
|
||||
try {
|
||||
ds_cap = env_context_area_ram_session()->alloc(ds_size);
|
||||
addr_t attach_addr = ds_addr - Native_config::context_area_virtual_base();
|
||||
env_context_area_rm_session()->attach_at(ds_cap, attach_addr, ds_size);
|
||||
|
||||
} catch (Ram_session::Alloc_failed) {
|
||||
throw Stack_alloc_failed();
|
||||
if (attach_addr != (addr_t)env_context_area_rm_session()->attach_at(ds_cap, attach_addr, ds_size))
|
||||
throw Stack_alloc_failed();
|
||||
}
|
||||
catch (Ram_session::Alloc_failed) { throw Stack_alloc_failed(); }
|
||||
|
||||
/*
|
||||
* Now the thread context is backed by memory, so it is safe to access its
|
||||
* members.
|
||||
*
|
||||
* We need to initalize the context object's memory with zeroes,
|
||||
* We need to initialize the context object's memory with zeroes,
|
||||
* otherwise the ds_cap isn't invalid. That would cause trouble
|
||||
* when the assignment operator of Native_capability is used.
|
||||
*/
|
||||
memset(context, 0, sizeof(Context));
|
||||
memset(context, 0, sizeof(Context) - sizeof(Context::utcb));
|
||||
context->thread_base = this;
|
||||
context->stack_base = ds_addr;
|
||||
context->ds_cap = ds_cap;
|
||||
|
||||
/*
|
||||
* The value at the top of the stack might get interpreted as return
|
||||
* address of the thread start function by GDB, so we set it to 0.
|
||||
*/
|
||||
*(addr_t*)context->stack_top() = 0;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_free_context()
|
||||
void Thread_base::_free_context(Context* context)
|
||||
{
|
||||
addr_t ds_addr = _context->stack_base - Native_config::context_area_virtual_base();
|
||||
Ram_dataspace_capability ds_cap = _context->ds_cap;
|
||||
_context_allocator()->free(this);
|
||||
addr_t ds_addr = context->stack_base - Native_config::context_area_virtual_base();
|
||||
Ram_dataspace_capability ds_cap = context->ds_cap;
|
||||
|
||||
/* call de-constructor explicitly before memory gets detached */
|
||||
context->~Context();
|
||||
|
||||
Genode::env_context_area_rm_session()->detach((void *)ds_addr);
|
||||
Genode::env_context_area_ram_session()->free(ds_cap);
|
||||
|
||||
/* context area ready for reuse */
|
||||
_context_allocator()->free(context);
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::name(char *dst, size_t dst_len)
|
||||
{
|
||||
snprintf(dst, min(dst_len, (size_t)Context::NAME_LEN), _context->name);
|
||||
snprintf(dst, min(dst_len, (size_t)Context::NAME_LEN), "%s", _context->name);
|
||||
}
|
||||
|
||||
|
||||
@@ -196,19 +137,34 @@ void Thread_base::join()
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Thread_base(const char *name, size_t stack_size)
|
||||
void* Thread_base::alloc_secondary_stack(char const *name, size_t stack_size)
|
||||
{
|
||||
Context *context = _alloc_context(stack_size, false);
|
||||
strncpy(context->name, name, sizeof(context->name));
|
||||
return (void *)context->stack_top();
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::free_secondary_stack(void* stack_addr)
|
||||
{
|
||||
addr_t base = Context_allocator::addr_to_base(stack_addr);
|
||||
_free_context(Context_allocator::base_to_context(base));
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Thread_base(const char *name, size_t stack_size, Type const type)
|
||||
:
|
||||
_list_element(this),
|
||||
_context(_alloc_context(stack_size)),
|
||||
_context(type == REINITIALIZED_MAIN ?
|
||||
_context : _alloc_context(stack_size, type == MAIN)),
|
||||
_join_lock(Lock::LOCKED)
|
||||
{
|
||||
strncpy(_context->name, name, sizeof(_context->name));
|
||||
_init_platform_thread();
|
||||
_init_platform_thread(type);
|
||||
}
|
||||
|
||||
|
||||
Thread_base::~Thread_base()
|
||||
{
|
||||
_deinit_platform_thread();
|
||||
_free_context();
|
||||
_free_context(_context);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Fiasco.OC specific thread bootstrap code
|
||||
* \author Stefan Kalkowski
|
||||
* \author Martin Stein
|
||||
* \date 2011-01-20
|
||||
*/
|
||||
|
||||
@@ -11,9 +12,38 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/construct_at.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
|
||||
/*****************************
|
||||
** Startup library support **
|
||||
*****************************/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void prepare_reinit_main_thread()
|
||||
{
|
||||
using namespace Genode;
|
||||
construct_at<Capability_map>(cap_map());
|
||||
cap_idx_alloc()->reinit();
|
||||
prepare_init_main_thread();
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
void Genode::Thread_base::_thread_bootstrap() { }
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
/*
|
||||
* \brief Generic definitions for the location of the thread-context area
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2013-02-12
|
||||
*/
|
||||
|
||||
#include <base/native_types.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
addr_t Native_config::context_area_virtual_base() { return 0x40000000UL; }
|
||||
@@ -2,6 +2,7 @@
|
||||
* \brief Fiasco-specific implementation of the non-core startup Thread API
|
||||
* \author Norman Feske
|
||||
* \author Stefan Kalkowski
|
||||
* \author Martin Stein
|
||||
* \date 2010-01-19
|
||||
*/
|
||||
|
||||
@@ -38,15 +39,26 @@ void Thread_base::_deinit_platform_thread()
|
||||
}
|
||||
|
||||
|
||||
void Genode::Thread_base::_init_platform_thread()
|
||||
void Thread_base::_init_platform_thread(Type type)
|
||||
{
|
||||
/* create thread at core */
|
||||
char buf[48];
|
||||
name(buf, sizeof(buf));
|
||||
_thread_cap = env()->cpu_session()->create_thread(buf);
|
||||
if (type == NORMAL)
|
||||
{
|
||||
/* create thread at core */
|
||||
char buf[48];
|
||||
name(buf, sizeof(buf));
|
||||
_thread_cap = env()->cpu_session()->create_thread(buf);
|
||||
|
||||
/* assign thread to protection domain */
|
||||
env()->pd_session()->bind_thread(_thread_cap);
|
||||
/* assign thread to protection domain */
|
||||
env()->pd_session()->bind_thread(_thread_cap);
|
||||
return;
|
||||
}
|
||||
/* adjust values whose computation differs for a main thread */
|
||||
_tid = Fiasco::MAIN_THREAD_CAP;
|
||||
_thread_cap = env()->parent()->main_thread_cap();
|
||||
|
||||
/* make thread object known to the Fiasco environment */
|
||||
addr_t const t = (addr_t)this;
|
||||
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_THREAD_OBJ] = t;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,9 +82,7 @@ void Thread_base::start()
|
||||
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
|
||||
|
||||
/* register initial IP and SP at core */
|
||||
addr_t thread_sp = (addr_t)&_context->stack[-4];
|
||||
thread_sp &= ~0xf; /* align initial stack to 16 byte boundary */
|
||||
env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, thread_sp);
|
||||
env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, _context->stack_top());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
# override default location of thread context area within core
|
||||
vpath thread_context_area.cc $(REP_DIR)/src/base/thread/arndale
|
||||
|
||||
include $(PRG_DIR)/../target.inc
|
||||
|
||||
LD_TEXT_ADDR = 0x80100000
|
||||
|
||||
@@ -33,7 +33,6 @@ SRC_CC = cap_session_component.cc \
|
||||
signal_source_component.cc \
|
||||
trace_session_component.cc \
|
||||
thread_start.cc \
|
||||
thread_context_area.cc \
|
||||
core_printf.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/core/include \
|
||||
|
||||
@@ -35,7 +35,7 @@ void Thread_base::_deinit_platform_thread()
|
||||
}
|
||||
|
||||
|
||||
void Genode::Thread_base::_init_platform_thread() { }
|
||||
void Thread_base::_init_platform_thread(Type) { }
|
||||
|
||||
|
||||
void Thread_base::start()
|
||||
@@ -56,7 +56,7 @@ void Thread_base::start()
|
||||
l4_utcb_tcr_u(pt->utcb())->user[UTCB_TCR_BADGE] = (unsigned long) pt->gate().local.idx();
|
||||
l4_utcb_tcr_u(pt->utcb())->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
|
||||
|
||||
pt->start((void *)_thread_start, _context->stack);
|
||||
pt->start((void *)_thread_start, stack_top());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* \brief Platform-specific helper functions for the _main() function
|
||||
* \author Christian Prochaska
|
||||
* \author Christian Helmuth
|
||||
* \date 2009-08-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
#include <base/native_types.h>
|
||||
#include <base/cap_map.h>
|
||||
|
||||
namespace Fiasco {
|
||||
#include <l4/sys/utcb.h>
|
||||
}
|
||||
|
||||
|
||||
namespace Genode { void platform_main_bootstrap(); }
|
||||
|
||||
|
||||
void Genode::platform_main_bootstrap()
|
||||
{
|
||||
static struct Bootstrap
|
||||
{
|
||||
enum { MAIN_THREAD_CAP_ID = 1 };
|
||||
|
||||
Bootstrap()
|
||||
{
|
||||
Cap_index *i(cap_map()->insert(MAIN_THREAD_CAP_ID, Fiasco::MAIN_THREAD_CAP));
|
||||
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE] = (unsigned long) i;
|
||||
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_THREAD_OBJ] = 0;
|
||||
}
|
||||
} bootstrap;
|
||||
}
|
||||
@@ -37,13 +37,15 @@ namespace Genode {
|
||||
/**
|
||||
* Thread-context area configuration.
|
||||
*/
|
||||
static addr_t context_area_virtual_base() { return 0x40000000UL; }
|
||||
static addr_t context_area_virtual_size() { return 0x10000000UL; }
|
||||
static constexpr addr_t context_area_virtual_base() {
|
||||
return 0x40000000UL; }
|
||||
static constexpr addr_t context_area_virtual_size() {
|
||||
return 0x10000000UL; }
|
||||
|
||||
/**
|
||||
* Size of virtual address region holding the context of one thread
|
||||
*/
|
||||
static addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
};
|
||||
|
||||
struct Native_pd_args { };
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
#include <kernel/interface.h>
|
||||
#include <base/native_capability.h>
|
||||
#include <base/stdint.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* base-hw includes */
|
||||
#include <kernel/log.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
@@ -48,44 +52,22 @@ namespace Genode
|
||||
inline Native_thread_id thread_invalid_id() { return 0; }
|
||||
|
||||
/**
|
||||
* Message that is communicated synchronously
|
||||
* Data bunch with variable size that is communicated between threads
|
||||
*
|
||||
* \param MAX_SIZE maximum size the object is allowed to take
|
||||
*/
|
||||
struct Msg
|
||||
{
|
||||
/**
|
||||
* Types of synchronously communicated messages
|
||||
*/
|
||||
struct Type
|
||||
{
|
||||
enum Id {
|
||||
INVALID = 0,
|
||||
STARTUP = 1,
|
||||
IPC = 2,
|
||||
};
|
||||
};
|
||||
|
||||
Type::Id type;
|
||||
uint8_t data[];
|
||||
};
|
||||
template <size_t MAX_SIZE>
|
||||
struct Message_tpl;
|
||||
|
||||
/**
|
||||
* Message that is communicated between user threads
|
||||
* Information that a thread creator hands out to a new thread
|
||||
*/
|
||||
struct Ipc_msg : Msg
|
||||
{
|
||||
size_t size;
|
||||
uint8_t data[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Message that is communicated from a thread creator to the new thread
|
||||
*/
|
||||
class Startup_msg;
|
||||
class Start_info;
|
||||
|
||||
/**
|
||||
* Memory region that is exclusive to every thread and known by the kernel
|
||||
*/
|
||||
struct Native_utcb;
|
||||
class Native_utcb;
|
||||
|
||||
struct Cap_dst_policy
|
||||
{
|
||||
@@ -124,23 +106,136 @@ namespace Genode
|
||||
/**
|
||||
* Thread-context area configuration.
|
||||
*/
|
||||
static addr_t context_area_virtual_base() { return 0x40000000UL; }
|
||||
static addr_t context_area_virtual_size() { return 0x10000000UL; }
|
||||
static constexpr addr_t context_area_virtual_base() {
|
||||
return 0x40000000UL; }
|
||||
static constexpr addr_t context_area_virtual_size() {
|
||||
return 0x10000000UL; }
|
||||
|
||||
/**
|
||||
* Size of virtual address region holding the context of one thread
|
||||
*/
|
||||
static addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
};
|
||||
|
||||
struct Native_pd_args { };
|
||||
}
|
||||
|
||||
class Genode::Startup_msg : public Msg
|
||||
template <Genode::size_t MAX_SIZE>
|
||||
class Genode::Message_tpl
|
||||
{
|
||||
private:
|
||||
|
||||
Native_thread_id _thread_id;
|
||||
size_t _data_size;
|
||||
uint8_t _data[];
|
||||
|
||||
/**
|
||||
* Return size of payload-preceding meta data
|
||||
*/
|
||||
size_t _header_size() const { return (addr_t)_data - (addr_t)this; }
|
||||
|
||||
/**
|
||||
* Return maximum payload size
|
||||
*/
|
||||
size_t _max_data_size() const { return MAX_SIZE - _header_size(); }
|
||||
|
||||
/**
|
||||
* Return size of header and current payload
|
||||
*/
|
||||
size_t _size() const { return _header_size() + _data_size; }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Get information about current await-request operation
|
||||
*
|
||||
* \return buf_base base of receive buffer
|
||||
* \return buf_size size of receive buffer
|
||||
*/
|
||||
void info_about_await_request(void * & buf_base, size_t & buf_size)
|
||||
const
|
||||
{
|
||||
buf_base = (void *)this;
|
||||
buf_size = MAX_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about current send-request operation
|
||||
*
|
||||
* \return msg_base base of complete send-message data
|
||||
* \return msg_size size of complete send-message data
|
||||
* \return buf_base base of receive buffer
|
||||
* \return buf_size size of receive buffer
|
||||
*/
|
||||
void info_about_send_request(void * & msg_base, size_t & msg_size,
|
||||
void * & buf_base, size_t & buf_size)
|
||||
const
|
||||
{
|
||||
msg_base = (void *)this;
|
||||
msg_size = _size();
|
||||
buf_base = (void *)this;
|
||||
buf_size = MAX_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about current send-reply operation
|
||||
*
|
||||
* \return msg_base base of complete send-message data
|
||||
* \return msg_size size of complete send-message data
|
||||
*/
|
||||
void info_about_send_reply(void * & msg_base, size_t & msg_size)
|
||||
const
|
||||
{
|
||||
msg_base = (void *)this;
|
||||
msg_size = _size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Install message that shall be send
|
||||
*
|
||||
* \param data base of payload
|
||||
* \param data_size size of payload
|
||||
* \param name local name that shall be the first payload word
|
||||
*/
|
||||
void prepare_send(void * const data, size_t data_size,
|
||||
unsigned const name)
|
||||
{
|
||||
/* limit data size */
|
||||
if (data_size > _max_data_size()) {
|
||||
Kernel::log() << "oversized message outgoing\n";
|
||||
data_size = _max_data_size();
|
||||
}
|
||||
/* copy data */
|
||||
*(unsigned *)_data = name;
|
||||
void * const data_dst = (void *)((addr_t)_data + sizeof(name));
|
||||
void * const data_src = (void *)((addr_t)data + sizeof(name));
|
||||
memcpy(data_dst, data_src, data_size - sizeof(name));
|
||||
_data_size = data_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read out message that was received
|
||||
*
|
||||
* \param buf_base base of read buffer
|
||||
* \param buf_size size of read buffer
|
||||
*/
|
||||
void finish_receive(void * const buf_base, size_t const buf_size)
|
||||
{
|
||||
/* limit data size */
|
||||
if (_data_size > buf_size) {
|
||||
Kernel::log() << "oversized message incoming\n";
|
||||
_data_size = buf_size;
|
||||
}
|
||||
/* copy data */
|
||||
memcpy(buf_base, _data, _data_size);
|
||||
}
|
||||
};
|
||||
|
||||
class Genode::Start_info
|
||||
{
|
||||
private:
|
||||
|
||||
Native_thread_id _thread_id;
|
||||
Native_capability _utcb_ds;
|
||||
|
||||
public:
|
||||
|
||||
@@ -149,63 +244,66 @@ class Genode::Startup_msg : public Msg
|
||||
*
|
||||
* \param thread_id kernel name of the thread that is started
|
||||
*/
|
||||
void init(Native_thread_id const thread_id)
|
||||
void init(Native_thread_id const thread_id,
|
||||
Native_capability const & utcb_ds)
|
||||
{
|
||||
_thread_id = thread_id;
|
||||
type = Msg::Type::STARTUP;
|
||||
_utcb_ds = utcb_ds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return kernel name of started thread message-type-save
|
||||
*/
|
||||
Native_thread_id thread_id() const
|
||||
{
|
||||
if (type == Msg::Type::STARTUP) { return _thread_id; }
|
||||
return thread_invalid_id();
|
||||
}
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Native_thread_id thread_id() const { return _thread_id; }
|
||||
Native_capability utcb_ds() const { return _utcb_ds; }
|
||||
};
|
||||
|
||||
struct Genode::Native_utcb
|
||||
class Genode::Native_utcb
|
||||
{
|
||||
union {
|
||||
uint8_t data[1 << MIN_MAPPING_SIZE_LOG2];
|
||||
Msg msg;
|
||||
Ipc_msg ipc_msg;
|
||||
Startup_msg startup_msg;
|
||||
private:
|
||||
|
||||
uint8_t _data[1 << MIN_MAPPING_SIZE_LOG2];
|
||||
|
||||
public:
|
||||
|
||||
typedef Message_tpl<sizeof(_data)/sizeof(_data[0])> Message;
|
||||
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Message * message() const { return (Message *)_data; }
|
||||
|
||||
Start_info * start_info() const { return (Start_info *)_data; }
|
||||
|
||||
size_t size() const { return sizeof(_data)/sizeof(_data[0]); }
|
||||
|
||||
void * base() const { return (void *)_data; }
|
||||
};
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
enum {
|
||||
VIRT_ADDR_SPACE_START = 0x1000,
|
||||
VIRT_ADDR_SPACE_SIZE = 0xfffef000,
|
||||
};
|
||||
|
||||
void call_wait_for_request(void * & buf_base, size_t & buf_size)
|
||||
/**
|
||||
* Return virtual UTCB location of main threads
|
||||
*/
|
||||
inline Native_utcb * main_thread_utcb()
|
||||
{
|
||||
msg.type = Msg::Type::INVALID;
|
||||
buf_base = base();
|
||||
buf_size = size();
|
||||
enum {
|
||||
VAS_TOP = VIRT_ADDR_SPACE_START + VIRT_ADDR_SPACE_SIZE,
|
||||
UTCB = VAS_TOP - sizeof(Native_utcb),
|
||||
UTCB_ALIGNED = UTCB & ~((1 << MIN_MAPPING_SIZE_LOG2) - 1),
|
||||
};
|
||||
return (Native_utcb *)UTCB_ALIGNED;
|
||||
}
|
||||
|
||||
void call_request_and_wait(void * & msg_base, size_t & msg_size,
|
||||
void * & buf_base, size_t & buf_size)
|
||||
{
|
||||
msg.type = Msg::Type::IPC;
|
||||
msg_base = ipc_msg_base();
|
||||
msg_size = ipc_msg_size();
|
||||
buf_base = base();
|
||||
buf_size = size();
|
||||
}
|
||||
|
||||
void call_reply(void * & msg_base, size_t & msg_size)
|
||||
{
|
||||
msg.type = Msg::Type::IPC;
|
||||
msg_base = ipc_msg_base();
|
||||
msg_size = ipc_msg_size();
|
||||
}
|
||||
|
||||
size_t size() { return sizeof(data) / sizeof(data[0]); }
|
||||
void * base() { return &data; }
|
||||
addr_t top() { return (addr_t)base() + size(); }
|
||||
void * ipc_msg_base() { return &ipc_msg; }
|
||||
size_t ipc_msg_size() { return ipc_msg_header_size() + ipc_msg.size; }
|
||||
size_t ipc_msg_max_size() { return top() - (addr_t)&ipc_msg; }
|
||||
size_t ipc_msg_header_size() { return (addr_t)ipc_msg.data - (addr_t)&ipc_msg; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _BASE__NATIVE_TYPES_H_ */
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
#include <base/signal.h>
|
||||
#include <pager/capability.h>
|
||||
|
||||
/* base-hw includes */
|
||||
#include <placement_new.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
class Cap_session;
|
||||
@@ -132,9 +135,38 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry,
|
||||
|
||||
Signal_context_capability _signal_context_cap;
|
||||
Thread_capability _thread_cap;
|
||||
bool _signal_valid;
|
||||
char _signal_buf[sizeof(Signal)];
|
||||
unsigned const _badge;
|
||||
|
||||
/**
|
||||
* Remember an incoming fault for handling
|
||||
*
|
||||
* \param s fault signal
|
||||
*/
|
||||
void _take_fault(Signal const & s)
|
||||
{
|
||||
new (_signal_buf) Signal(s);
|
||||
_signal_valid = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* End handling of current fault
|
||||
*/
|
||||
void _end_fault()
|
||||
{
|
||||
_signal()->~Signal();
|
||||
_signal_valid = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* End handling of current fault if there is one
|
||||
*/
|
||||
void _end_fault_if_pending()
|
||||
{
|
||||
if (_signal_valid) { _end_fault(); }
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
@@ -151,27 +183,22 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry,
|
||||
*/
|
||||
Pager_object(unsigned const badge, Affinity::Location);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~Pager_object() { }
|
||||
|
||||
/**
|
||||
* The faulter has caused a fault and awaits paging
|
||||
*
|
||||
* \param s signal that communicated the fault
|
||||
*/
|
||||
void fault_occured(Signal const & s);
|
||||
void fault_occured(Signal const & s) { _take_fault(s); }
|
||||
|
||||
/**
|
||||
* Current fault has been resolved so resume faulter
|
||||
*/
|
||||
void fault_resolved();
|
||||
void fault_resolved() { _end_fault(); }
|
||||
|
||||
/**
|
||||
* User identification of pager object
|
||||
*/
|
||||
unsigned badge() const;
|
||||
unsigned badge() const { return _badge; }
|
||||
|
||||
/**
|
||||
* Resume faulter
|
||||
@@ -183,6 +210,29 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry,
|
||||
*/
|
||||
void exception_handler(Signal_context_capability);
|
||||
|
||||
/**
|
||||
* Install information that is necessary to handle page faults
|
||||
*
|
||||
* \param c linkage between signal context and a signal receiver
|
||||
* \param p linkage between pager object and a pager entry-point
|
||||
*/
|
||||
void start_paging(Signal_context_capability const & c,
|
||||
Pager_capability const & p)
|
||||
{
|
||||
_signal_context_cap = c;
|
||||
Object_pool<Pager_object>::Entry::cap(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall paging information and cancel unresolved faults
|
||||
*/
|
||||
void stop_paging()
|
||||
{
|
||||
Object_pool<Pager_object>::Entry::cap(Native_capability());
|
||||
_signal_context_cap = Signal_context_capability();
|
||||
_end_fault_if_pending();
|
||||
}
|
||||
|
||||
|
||||
/******************
|
||||
** Pure virtual **
|
||||
@@ -207,8 +257,6 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry,
|
||||
|
||||
void thread_cap(Thread_capability const & c);
|
||||
|
||||
void cap(Native_capability const & c);
|
||||
|
||||
unsigned signal_context_id() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Serial output driver for console lib
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2013-01-09
|
||||
*/
|
||||
|
||||
@@ -11,19 +12,19 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__ARNDALE_UART__DRIVERS__SERIAL_LOG_H_
|
||||
#define _INCLUDE__ARNDALE_UART__DRIVERS__SERIAL_LOG_H_
|
||||
#ifndef _INCLUDE__EXYNOS_UART__DRIVERS__SERIAL_LOG_H_
|
||||
#define _INCLUDE__EXYNOS_UART__DRIVERS__SERIAL_LOG_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <board.h>
|
||||
#include <drivers/uart/arndale_uart_base.h>
|
||||
#include <drivers/uart/exynos_uart_base.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Serial output driver for console lib
|
||||
*/
|
||||
class Serial_log : public Arndale_uart_base
|
||||
class Serial_log : public Exynos_uart_base
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -33,11 +34,11 @@ namespace Genode
|
||||
* \param baud_rate targeted transfer baud-rate
|
||||
*/
|
||||
Serial_log(unsigned const baud_rate) :
|
||||
Arndale_uart_base(Board::UART_2_MMIO_BASE,
|
||||
Board::UART_2_CLOCK, baud_rate)
|
||||
Exynos_uart_base(Board::UART_2_MMIO_BASE,
|
||||
Board::UART_2_CLOCK, baud_rate)
|
||||
{ }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__ARNDALE_UART__DRIVERS__SERIAL_LOG_H_ */
|
||||
#endif /* _INCLUDE__EXYNOS_UART__DRIVERS__SERIAL_LOG_H_ */
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Kernel
|
||||
{
|
||||
enum {
|
||||
NEW_THREAD = 0,
|
||||
KILL_THREAD = 1,
|
||||
BIN_THREAD = 1,
|
||||
START_THREAD = 2,
|
||||
PAUSE_THREAD = 3,
|
||||
RESUME_THREAD = 4,
|
||||
@@ -49,22 +49,23 @@ namespace Kernel
|
||||
UPDATE_PD = 8,
|
||||
UPDATE_REGION = 9,
|
||||
NEW_PD = 10,
|
||||
KILL_PD = 11,
|
||||
REQUEST_AND_WAIT = 12,
|
||||
REPLY = 13,
|
||||
WAIT_FOR_REQUEST = 14,
|
||||
BIN_PD = 11,
|
||||
SEND_REQUEST_MSG = 12,
|
||||
SEND_REPLY_MSG = 13,
|
||||
AWAIT_REQUEST_MSG = 14,
|
||||
NEW_SIGNAL_RECEIVER = 15,
|
||||
NEW_SIGNAL_CONTEXT = 16,
|
||||
KILL_SIGNAL_CONTEXT = 17,
|
||||
KILL_SIGNAL_RECEIVER = 18,
|
||||
SUBMIT_SIGNAL = 19,
|
||||
AWAIT_SIGNAL = 20,
|
||||
SIGNAL_PENDING = 21,
|
||||
ACK_SIGNAL = 22,
|
||||
NEW_VM = 23,
|
||||
RUN_VM = 24,
|
||||
PAUSE_VM = 25,
|
||||
PRINT_CHAR = 26,
|
||||
BIN_SIGNAL_CONTEXT = 18,
|
||||
BIN_SIGNAL_RECEIVER = 19,
|
||||
SUBMIT_SIGNAL = 20,
|
||||
AWAIT_SIGNAL = 21,
|
||||
SIGNAL_PENDING = 22,
|
||||
ACK_SIGNAL = 23,
|
||||
NEW_VM = 24,
|
||||
RUN_VM = 25,
|
||||
PAUSE_VM = 26,
|
||||
PRINT_CHAR = 27,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -151,9 +152,9 @@ namespace Kernel
|
||||
* \retval 0 succeeded
|
||||
* \retval -1 failed
|
||||
*/
|
||||
inline int kill_pd(unsigned const pd_id)
|
||||
inline int bin_pd(unsigned const pd_id)
|
||||
{
|
||||
return call(Call_id::KILL_PD, pd_id);
|
||||
return call(Call_id::BIN_PD, pd_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -223,9 +224,9 @@ namespace Kernel
|
||||
*
|
||||
* Restricted to core threads.
|
||||
*/
|
||||
inline void kill_thread(unsigned const thread_id)
|
||||
inline void bin_thread(unsigned const thread_id)
|
||||
{
|
||||
call(Call_id::KILL_THREAD, thread_id);
|
||||
call(Call_id::BIN_THREAD, thread_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -315,47 +316,59 @@ namespace Kernel
|
||||
|
||||
|
||||
/**
|
||||
* Send IPC request and await corresponding IPC reply
|
||||
* Send request message and await receipt of corresponding reply message
|
||||
*
|
||||
* \param id kernel name of the server thread
|
||||
* \param thread_id kernel name of targeted thread
|
||||
*
|
||||
* As soon as call returns, callers UTCB provides received message.
|
||||
* \retval 0 succeeded
|
||||
* \retval -1 failed
|
||||
*
|
||||
* If the call returns successful, the received message is located at the
|
||||
* base of the callers userland thread-context.
|
||||
*/
|
||||
inline void request_and_wait(unsigned const id)
|
||||
inline int send_request_msg(unsigned const thread_id)
|
||||
{
|
||||
call(Call_id::REQUEST_AND_WAIT, id);
|
||||
return call(Call_id::SEND_REQUEST_MSG, thread_id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Await the receipt of a message
|
||||
* Await receipt of request message
|
||||
*
|
||||
* \return type of received message
|
||||
* \retval 0 succeeded
|
||||
* \retval -1 failed
|
||||
*
|
||||
* As soon as call returns, callers UTCB provides received message.
|
||||
* If the call returns successful, the received message is located at the
|
||||
* base of the callers userland thread-context.
|
||||
*/
|
||||
inline void wait_for_request()
|
||||
inline int await_request_msg()
|
||||
{
|
||||
call(Call_id::WAIT_FOR_REQUEST);
|
||||
return call(Call_id::AWAIT_REQUEST_MSG);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reply to lastly received message
|
||||
* Reply to lastly received request message
|
||||
*
|
||||
* \param await_message wether the call shall await receipt of a message
|
||||
* \param await_request_msg wether the call shall await a request message
|
||||
*
|
||||
* If await_request = 1, callers UTCB provides received message
|
||||
* as soon as call returns
|
||||
* \retval 0 await_request_msg == 0 or request-message receipt succeeded
|
||||
* \retval -1 await_request_msg == 1 and request-message receipt failed
|
||||
*
|
||||
* If the call returns successful and await_request_msg == 1, the received
|
||||
* message is located at the base of the callers userland thread-context.
|
||||
*/
|
||||
inline void reply(bool const await_message)
|
||||
inline int send_reply_msg(bool const await_request_msg)
|
||||
{
|
||||
call(Call_id::REPLY, await_message);
|
||||
return call(Call_id::SEND_REPLY_MSG, await_request_msg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print a char 'c' to the kernels serial ouput
|
||||
* Print a char c to the kernels serial ouput
|
||||
*
|
||||
* If c is set to 0 the kernel prints a table of all threads and their
|
||||
* current activities to the serial output.
|
||||
*/
|
||||
inline void print_char(char const c)
|
||||
{
|
||||
@@ -510,6 +523,20 @@ namespace Kernel
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Halt processing of a signal context synchronously
|
||||
*
|
||||
* \param context kernel name of the targeted signal context
|
||||
*
|
||||
* \retval 0 suceeded
|
||||
* \retval -1 failed
|
||||
*/
|
||||
inline int kill_signal_context(unsigned const context)
|
||||
{
|
||||
return call(Call_id::KILL_SIGNAL_CONTEXT, context);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destruct a signal context
|
||||
*
|
||||
@@ -520,9 +547,9 @@ namespace Kernel
|
||||
*
|
||||
* Restricted to core threads.
|
||||
*/
|
||||
inline int kill_signal_context(unsigned const context)
|
||||
inline int bin_signal_context(unsigned const context)
|
||||
{
|
||||
return call(Call_id::KILL_SIGNAL_CONTEXT, context);
|
||||
return call(Call_id::BIN_SIGNAL_CONTEXT, context);
|
||||
}
|
||||
|
||||
|
||||
@@ -536,9 +563,9 @@ namespace Kernel
|
||||
*
|
||||
* Restricted to core threads.
|
||||
*/
|
||||
inline int kill_signal_receiver(unsigned const receiver)
|
||||
inline int bin_signal_receiver(unsigned const receiver)
|
||||
{
|
||||
return call(Call_id::KILL_SIGNAL_RECEIVER, receiver);
|
||||
return call(Call_id::BIN_SIGNAL_RECEIVER, receiver);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* \brief Print to kernel log output
|
||||
* \brief Print to the standard output of the kernel
|
||||
* \author Martin stein
|
||||
* \date 2012-04-05
|
||||
*/
|
||||
@@ -17,42 +17,45 @@
|
||||
/* Genode includes */
|
||||
#include <kernel/interface.h>
|
||||
|
||||
namespace Genode
|
||||
namespace Kernel
|
||||
{
|
||||
/**
|
||||
* Prints incoming streams to the kernel log output
|
||||
* Prints incoming streams to the standard output of the kernel
|
||||
*/
|
||||
class Kernel_log
|
||||
class Log
|
||||
{
|
||||
/**
|
||||
* Print an unsigned 4 bit integer as hexadecimal value
|
||||
*/
|
||||
void _print_4bit_hex(unsigned char x) const
|
||||
{
|
||||
/* decode to ASCII char */
|
||||
x &= 0x0f;
|
||||
if (x > 9) x += 39;
|
||||
x += 48;
|
||||
private:
|
||||
|
||||
/* print ASCII char */
|
||||
Kernel::print_char(x);
|
||||
}
|
||||
/**
|
||||
* Print an unsigned 4 bit integer x as hexadecimal value
|
||||
*/
|
||||
void _print_4bit_hex(unsigned char x) const
|
||||
{
|
||||
/* decode to ASCII char */
|
||||
x &= 0x0f;
|
||||
if (x > 9) x += 39;
|
||||
x += 48;
|
||||
|
||||
/* print ASCII char */
|
||||
print_char(x);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Print zero-terminated string
|
||||
* Print a zero-terminated string s
|
||||
*/
|
||||
Kernel_log & operator << (char const * s)
|
||||
Log & operator << (char const * s)
|
||||
{
|
||||
while (*s) Kernel::print_char(*s++);
|
||||
while (*s) print_char(*s++);
|
||||
if (*--s != '\n') { print_char(' '); }
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an unsigned integer as hexadecimal value
|
||||
* Print an unsigned integer x as hexadecimal value
|
||||
*/
|
||||
Kernel_log & operator << (unsigned int const & x)
|
||||
Log & operator << (unsigned int const x)
|
||||
{
|
||||
enum {
|
||||
BYTE_WIDTH = 8,
|
||||
@@ -91,17 +94,23 @@ namespace Genode
|
||||
_print_4bit_hex(c >> 4);
|
||||
_print_4bit_hex(c);
|
||||
}
|
||||
print_char(' ');
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a pointer p as hexadecimal value
|
||||
*/
|
||||
Log & operator << (void * const p) { return *this << (unsigned)p; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Give static 'Kernel_log' reference as target for common log output
|
||||
* Return singleton kernel-log
|
||||
*/
|
||||
inline Kernel_log & kernel_log()
|
||||
inline Log & log()
|
||||
{
|
||||
static Kernel_log _log;
|
||||
return _log;
|
||||
static Log s;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,10 +20,16 @@
|
||||
namespace Trustzone
|
||||
{
|
||||
enum {
|
||||
VM_STATE_SIZE = 1 << 20,
|
||||
/**
|
||||
* Currently, we limit secure RAM to 256 MB only,
|
||||
* because the memory protection feature of the M4IF
|
||||
* on this platform allows to protect a max. region of
|
||||
* 256MB per RAM bank only.
|
||||
*/
|
||||
SECURE_RAM_BASE = Genode::Board_base::RAM0_BASE,
|
||||
SECURE_RAM_SIZE = Genode::Board_base::RAM0_SIZE - VM_STATE_SIZE,
|
||||
SECURE_RAM_SIZE = 256 * 1024 * 1024,
|
||||
VM_STATE_BASE = SECURE_RAM_BASE + SECURE_RAM_SIZE,
|
||||
VM_STATE_SIZE = 1 << 20,
|
||||
NONSECURE_RAM_BASE = Genode::Board_base::RAM1_BASE,
|
||||
NONSECURE_RAM_SIZE = Genode::Board_base::RAM1_SIZE,
|
||||
};
|
||||
|
||||
3
base-hw/lib/mk/arm/base-common.mk
Normal file
3
base-hw/lib/mk/arm/base-common.mk
Normal file
@@ -0,0 +1,3 @@
|
||||
include $(REP_DIR)/lib/mk/base-common.inc
|
||||
|
||||
vpath kernel/interface.cc $(REP_DIR)/src/arm
|
||||
@@ -1,2 +0,0 @@
|
||||
SRC_CC = kernel/interface.cc
|
||||
vpath % $(REP_DIR)/src/arm
|
||||
@@ -1,12 +1,12 @@
|
||||
#
|
||||
# \brief Portions of base library shared by core and non-core processes
|
||||
# \author Norman Feske
|
||||
# \author Martin Stein
|
||||
# \date 2013-02-14
|
||||
#
|
||||
|
||||
LIBS += cxx kernel_interface
|
||||
LIBS += cxx
|
||||
|
||||
SRC_CC += main_bootstrap.cc
|
||||
SRC_CC += ipc.cc ipc/ipc_marshal_cap.cc
|
||||
SRC_CC += avl_tree/avl_tree.cc
|
||||
SRC_CC += allocator/slab.cc
|
||||
@@ -20,11 +20,12 @@ SRC_CC += lock/lock.cc
|
||||
SRC_CC += signal/signal.cc signal/common.cc
|
||||
SRC_CC += server/server.cc server/common.cc
|
||||
SRC_CC += thread/thread_bootstrap.cc thread/trace.cc
|
||||
SRC_CC += thread/context_allocator.cc
|
||||
SRC_CC += kernel/interface.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/base/lock
|
||||
INC_DIR += $(REP_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/thread
|
||||
|
||||
vpath main_bootstrap.cc $(REP_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
@@ -7,7 +7,7 @@
|
||||
LIBS += base-common startup
|
||||
|
||||
SRC_CC += console/log_console.cc
|
||||
SRC_CC += env/env.cc env/context_area.cc env/reload_parent_cap.cc
|
||||
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
|
||||
SRC_CC += thread/thread.cc thread_support.cc
|
||||
|
||||
INC_DIR += $(BASE_DIR)/src/base/env
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# \brief Offer build configurations that are specific to base-hw and Pandaboard A2
|
||||
# \brief Offer build configurations that are specific to base-hw and Arndale
|
||||
# \author Martin Stein
|
||||
# \date 2013-01-09
|
||||
#
|
||||
@@ -7,6 +7,9 @@
|
||||
# denote wich specs are also fullfilled by this spec
|
||||
SPECS += hw platform_arndale
|
||||
|
||||
# add repository relative paths
|
||||
REP_INC_DIR += include/exynos5_uart
|
||||
|
||||
# set address where to link the text segment at
|
||||
LD_TEXT_ADDR ?= 0x80000000
|
||||
|
||||
|
||||
18
base-hw/mk/spec-hw_odroid_xu.mk
Normal file
18
base-hw/mk/spec-hw_odroid_xu.mk
Normal file
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# \brief Offer build configurations that are specific to base-hw and Odroid XU
|
||||
# \author Stefan Kalkowski
|
||||
# \date 2013-11-25
|
||||
#
|
||||
|
||||
# denote wich specs are also fullfilled by this spec
|
||||
SPECS += hw platform_odroid_xu
|
||||
|
||||
# add repository relative paths
|
||||
REP_INC_DIR += include/exynos5_uart
|
||||
|
||||
# set address where to link the text segment at
|
||||
LD_TEXT_ADDR ?= 0x80000000
|
||||
|
||||
# include implied specs
|
||||
include $(call select_from_repositories,mk/spec-hw.mk)
|
||||
include $(call select_from_repositories,mk/spec-platform_odroid_xu.mk)
|
||||
@@ -8,7 +8,7 @@
|
||||
SPECS += hw platform_panda
|
||||
|
||||
# set address where to link the text segment at
|
||||
LD_TEXT_ADDR ?= 0x80000000
|
||||
LD_TEXT_ADDR ?= 0x81000000
|
||||
|
||||
# include implied specs
|
||||
include $(call select_from_repositories,mk/spec-hw.mk)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
SPECS += hw platform_pbxa9
|
||||
|
||||
# set address where to link text segment at
|
||||
LD_TEXT_ADDR ?= 0x01000000
|
||||
LD_TEXT_ADDR ?= 0x70000000
|
||||
|
||||
# include implied specs
|
||||
include $(call select_from_repositories,mk/spec-hw.mk)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* \brief Interface between kernel and userland
|
||||
* \author Martin stein
|
||||
* \author Martin Stein
|
||||
* \date 2011-11-30
|
||||
*/
|
||||
|
||||
@@ -17,91 +17,59 @@
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
** Inline assembly templates for kernel calls with 1 to 6 arguments **
|
||||
**********************************************************************/
|
||||
|
||||
#define CALL_6_ASM_OPS \
|
||||
"mov r5, #0 \n" \
|
||||
"add r5, %[arg_5] \n" \
|
||||
CALL_5_ASM_OPS
|
||||
|
||||
#define CALL_5_ASM_OPS \
|
||||
"mov r4, #0 \n" \
|
||||
"add r4, %[arg_4] \n" \
|
||||
CALL_4_ASM_OPS
|
||||
|
||||
#define CALL_4_ASM_OPS \
|
||||
"mov r3, #0 \n" \
|
||||
"add r3, %[arg_3] \n" \
|
||||
CALL_3_ASM_OPS
|
||||
|
||||
#define CALL_3_ASM_OPS \
|
||||
"mov r2, #0 \n" \
|
||||
"add r2, %[arg_2] \n" \
|
||||
CALL_2_ASM_OPS
|
||||
|
||||
#define CALL_2_ASM_OPS \
|
||||
"mov r1, #0 \n" \
|
||||
"add r1, %[arg_1] \n" \
|
||||
CALL_1_ASM_OPS
|
||||
|
||||
#define CALL_1_ASM_OPS \
|
||||
"mov r0, #0 \n" \
|
||||
"add r0, %[arg_0] \n" \
|
||||
"swi 0 \n" \
|
||||
"mov %[result], #0 \n" \
|
||||
"add %[result], r0 "
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Inline assembly "writeable" tpl-args for kernel calls with 1 to 6 args **
|
||||
****************************************************************************/
|
||||
|
||||
#define CALL_6_ASM_WRITE [arg_5] "+r" (arg_5), CALL_5_ASM_WRITE
|
||||
#define CALL_5_ASM_WRITE [arg_4] "+r" (arg_4), CALL_4_ASM_WRITE
|
||||
#define CALL_4_ASM_WRITE [arg_3] "+r" (arg_3), CALL_3_ASM_WRITE
|
||||
#define CALL_3_ASM_WRITE [arg_2] "+r" (arg_2), CALL_2_ASM_WRITE
|
||||
#define CALL_2_ASM_WRITE [arg_1] "+r" (arg_1), CALL_1_ASM_WRITE
|
||||
#define CALL_1_ASM_WRITE \
|
||||
[arg_0] "+r" (arg_0), \
|
||||
[result] "+r" (result)
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
** Inline assembly clobber lists for kernel calls with 1 to 6 arguments **
|
||||
**************************************************************************/
|
||||
|
||||
#define CALL_6_ASM_CLOBBER "r5", CALL_5_ASM_CLOBBER
|
||||
#define CALL_5_ASM_CLOBBER "r4", CALL_4_ASM_CLOBBER
|
||||
#define CALL_4_ASM_CLOBBER "r3", CALL_3_ASM_CLOBBER
|
||||
#define CALL_3_ASM_CLOBBER "r2", CALL_2_ASM_CLOBBER
|
||||
#define CALL_2_ASM_CLOBBER "r1", CALL_1_ASM_CLOBBER
|
||||
#define CALL_1_ASM_CLOBBER "r0"
|
||||
|
||||
|
||||
/************************************
|
||||
** Calls with 1 to 6 arguments **
|
||||
** Helper macros for kernel calls **
|
||||
************************************/
|
||||
|
||||
#define CALL_1_FILL_ARG_REGS \
|
||||
register Call_arg arg_0_reg asm("r0") = arg_0;
|
||||
|
||||
#define CALL_2_FILL_ARG_REGS \
|
||||
CALL_1_FILL_ARG_REGS \
|
||||
register Call_arg arg_1_reg asm("r1") = arg_1;
|
||||
|
||||
#define CALL_3_FILL_ARG_REGS \
|
||||
CALL_2_FILL_ARG_REGS \
|
||||
register Call_arg arg_2_reg asm("r2") = arg_2;
|
||||
|
||||
#define CALL_4_FILL_ARG_REGS \
|
||||
CALL_3_FILL_ARG_REGS \
|
||||
register Call_arg arg_3_reg asm("r3") = arg_3;
|
||||
|
||||
#define CALL_5_FILL_ARG_REGS \
|
||||
CALL_4_FILL_ARG_REGS \
|
||||
register Call_arg arg_4_reg asm("r4") = arg_4;
|
||||
|
||||
#define CALL_6_FILL_ARG_REGS \
|
||||
CALL_5_FILL_ARG_REGS \
|
||||
register Call_arg arg_5_reg asm("r5") = arg_5;
|
||||
|
||||
#define CALL_1_SWI "swi 0\n" : "+r" (arg_0_reg)
|
||||
#define CALL_2_SWI CALL_1_SWI: "r" (arg_1_reg)
|
||||
#define CALL_3_SWI CALL_2_SWI, "r" (arg_2_reg)
|
||||
#define CALL_4_SWI CALL_3_SWI, "r" (arg_3_reg)
|
||||
#define CALL_5_SWI CALL_4_SWI, "r" (arg_4_reg)
|
||||
#define CALL_6_SWI CALL_5_SWI, "r" (arg_5_reg)
|
||||
|
||||
|
||||
/******************
|
||||
** Kernel calls **
|
||||
******************/
|
||||
|
||||
Call_ret Kernel::call(Call_arg arg_0)
|
||||
{
|
||||
Call_ret result = 0;
|
||||
asm volatile(CALL_1_ASM_OPS
|
||||
: CALL_1_ASM_WRITE
|
||||
:: CALL_1_ASM_CLOBBER);
|
||||
return result;
|
||||
CALL_1_FILL_ARG_REGS
|
||||
asm volatile(CALL_1_SWI);
|
||||
return arg_0_reg;
|
||||
}
|
||||
|
||||
|
||||
Call_ret Kernel::call(Call_arg arg_0,
|
||||
Call_arg arg_1)
|
||||
{
|
||||
Call_ret result = 0;
|
||||
asm volatile(CALL_2_ASM_OPS
|
||||
: CALL_2_ASM_WRITE
|
||||
:: CALL_2_ASM_CLOBBER);
|
||||
return result;
|
||||
CALL_2_FILL_ARG_REGS
|
||||
asm volatile(CALL_2_SWI);
|
||||
return arg_0_reg;
|
||||
}
|
||||
|
||||
|
||||
@@ -109,11 +77,9 @@ Call_ret Kernel::call(Call_arg arg_0,
|
||||
Call_arg arg_1,
|
||||
Call_arg arg_2)
|
||||
{
|
||||
Call_ret result = 0;
|
||||
asm volatile(CALL_3_ASM_OPS
|
||||
: CALL_3_ASM_WRITE
|
||||
:: CALL_3_ASM_CLOBBER);
|
||||
return result;
|
||||
CALL_3_FILL_ARG_REGS
|
||||
asm volatile(CALL_3_SWI);
|
||||
return arg_0_reg;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,11 +88,9 @@ Call_ret Kernel::call(Call_arg arg_0,
|
||||
Call_arg arg_2,
|
||||
Call_arg arg_3)
|
||||
{
|
||||
Call_ret result = 0;
|
||||
asm volatile(CALL_4_ASM_OPS
|
||||
: CALL_4_ASM_WRITE
|
||||
:: CALL_4_ASM_CLOBBER);
|
||||
return result;
|
||||
CALL_4_FILL_ARG_REGS
|
||||
asm volatile(CALL_4_SWI);
|
||||
return arg_0_reg;
|
||||
}
|
||||
|
||||
|
||||
@@ -136,11 +100,9 @@ Call_ret Kernel::call(Call_arg arg_0,
|
||||
Call_arg arg_3,
|
||||
Call_arg arg_4)
|
||||
{
|
||||
Call_ret result = 0;
|
||||
asm volatile(CALL_5_ASM_OPS
|
||||
: CALL_5_ASM_WRITE
|
||||
:: CALL_5_ASM_CLOBBER);
|
||||
return result;
|
||||
CALL_5_FILL_ARG_REGS
|
||||
asm volatile(CALL_5_SWI);
|
||||
return arg_0_reg;
|
||||
}
|
||||
|
||||
|
||||
@@ -151,11 +113,9 @@ Call_ret Kernel::call(Call_arg arg_0,
|
||||
Call_arg arg_4,
|
||||
Call_arg arg_5)
|
||||
{
|
||||
Call_ret result = 0;
|
||||
asm volatile(CALL_6_ASM_OPS
|
||||
: CALL_6_ASM_WRITE
|
||||
:: CALL_6_ASM_CLOBBER);
|
||||
return result;
|
||||
CALL_6_FILL_ARG_REGS
|
||||
asm volatile(CALL_6_SWI);
|
||||
return arg_0_reg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
#include <base/printf.h>
|
||||
#include <drivers/serial_log.h>
|
||||
|
||||
/* base-hw includes */
|
||||
#include "singleton.h"
|
||||
/* base includes */
|
||||
#include <unmanaged_singleton.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
@@ -66,7 +66,7 @@ using namespace Genode;
|
||||
*/
|
||||
static Platform_console * platform_console()
|
||||
{
|
||||
return unsynchronized_singleton<Platform_console>();
|
||||
return unmanaged_singleton<Platform_console>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,46 +35,6 @@ enum
|
||||
};
|
||||
|
||||
|
||||
/***************
|
||||
** Utilities **
|
||||
***************/
|
||||
|
||||
/**
|
||||
* Copy message from the callers UTCB to message buffer
|
||||
*/
|
||||
static void utcb_to_msgbuf(Msgbuf_base * const msgbuf)
|
||||
{
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
size_t msg_size = utcb->ipc_msg.size;
|
||||
if (msg_size > msgbuf->size()) {
|
||||
kernel_log() << "oversized IPC message\n";
|
||||
msg_size = msgbuf->size();
|
||||
}
|
||||
memcpy(msgbuf->buf, utcb->ipc_msg.data, msg_size);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy message from message buffer to the callers UTCB
|
||||
*/
|
||||
static void msgbuf_to_utcb(Msgbuf_base * const msg_buf, size_t msg_size,
|
||||
unsigned const local_name)
|
||||
{
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
enum { NAME_SIZE = sizeof(local_name) };
|
||||
size_t const ipc_msg_size = msg_size + NAME_SIZE;
|
||||
if (ipc_msg_size > utcb->ipc_msg_max_size()) {
|
||||
kernel_log() << "oversized IPC message\n";
|
||||
msg_size = utcb->ipc_msg_max_size() - NAME_SIZE;
|
||||
}
|
||||
*(unsigned *)utcb->ipc_msg.data = local_name;
|
||||
void * const utcb_msg = (void *)((addr_t)utcb->ipc_msg.data + NAME_SIZE);
|
||||
void * const buf_msg = (void *)((addr_t)msg_buf->buf + NAME_SIZE);
|
||||
memcpy(utcb_msg, buf_msg, msg_size);
|
||||
utcb->ipc_msg.size = ipc_msg_size;
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Ipc_ostream **
|
||||
*****************/
|
||||
@@ -116,20 +76,15 @@ Ipc_istream::~Ipc_istream() { }
|
||||
|
||||
void Ipc_client::_call()
|
||||
{
|
||||
using namespace Kernel;
|
||||
|
||||
/* send request */
|
||||
/* send request and receive corresponding reply */
|
||||
unsigned const local_name = Ipc_ostream::_dst.local_name();
|
||||
msgbuf_to_utcb(_snd_msg, _write_offset, local_name);
|
||||
request_and_wait(Ipc_ostream::_dst.dst());
|
||||
|
||||
/* receive reply */
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
if (utcb->msg.type != Msg::Type::IPC) {
|
||||
utcb->message()->prepare_send(_snd_msg->buf, _write_offset, local_name);
|
||||
if (Kernel::send_request_msg(Ipc_ostream::_dst.dst())) {
|
||||
PERR("failed to receive reply");
|
||||
throw Blocking_canceled();
|
||||
}
|
||||
utcb_to_msgbuf(_rcv_msg);
|
||||
utcb->message()->finish_receive(_rcv_msg->buf, _rcv_msg->size());
|
||||
|
||||
/* reset unmarshaller */
|
||||
_write_offset = _read_offset = RPC_OBJECT_ID_SIZE;
|
||||
@@ -168,14 +123,13 @@ void Ipc_server::_prepare_next_reply_wait()
|
||||
|
||||
void Ipc_server::_wait()
|
||||
{
|
||||
/* receive next request */
|
||||
Kernel::wait_for_request();
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
if (utcb->msg.type != Msg::Type::IPC) {
|
||||
/* receive request */
|
||||
if (Kernel::await_request_msg()) {
|
||||
PERR("failed to receive request");
|
||||
throw Blocking_canceled();
|
||||
}
|
||||
utcb_to_msgbuf(_rcv_msg);
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
utcb->message()->finish_receive(_rcv_msg->buf, _rcv_msg->size());
|
||||
|
||||
/* update server state */
|
||||
_prepare_next_reply_wait();
|
||||
@@ -184,9 +138,10 @@ void Ipc_server::_wait()
|
||||
|
||||
void Ipc_server::_reply()
|
||||
{
|
||||
unsigned const local_name = Ipc_ostream::_dst.local_name();
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
utcb->ipc_msg.size = _write_offset;
|
||||
Kernel::reply(0);
|
||||
utcb->message()->prepare_send(_snd_msg->buf, _write_offset, local_name);
|
||||
Kernel::send_reply_msg(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -197,20 +152,16 @@ void Ipc_server::_reply_wait()
|
||||
_wait();
|
||||
return;
|
||||
}
|
||||
/* send reply an await request */
|
||||
/* send reply and receive next request */
|
||||
unsigned const local_name = Ipc_ostream::_dst.local_name();
|
||||
msgbuf_to_utcb(_snd_msg, _write_offset, local_name);
|
||||
Kernel::reply(1);
|
||||
|
||||
/* fetch request */
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
if (utcb->msg.type != Msg::Type::IPC) {
|
||||
utcb->message()->prepare_send(_snd_msg->buf, _write_offset, local_name);
|
||||
if (Kernel::send_reply_msg(true)) {
|
||||
PERR("failed to receive request");
|
||||
throw Blocking_canceled();
|
||||
}
|
||||
utcb_to_msgbuf(_rcv_msg);
|
||||
utcb->message()->finish_receive(_rcv_msg->buf, _rcv_msg->size());
|
||||
|
||||
/* update server state */
|
||||
_prepare_next_reply_wait();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
#include <base/pager.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
/* base-hw includes */
|
||||
#include <placement_new.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
@@ -70,25 +67,10 @@ void Pager_object::wake_up() { fault_resolved(); }
|
||||
|
||||
void Pager_object::exception_handler(Signal_context_capability) { }
|
||||
|
||||
void Pager_object::fault_resolved() { _signal()->~Signal(); }
|
||||
|
||||
unsigned Pager_object::badge() const { return _badge; }
|
||||
|
||||
|
||||
void Pager_object::fault_occured(Signal const & s)
|
||||
{
|
||||
new (_signal()) Signal(s);
|
||||
}
|
||||
|
||||
|
||||
void Pager_object::cap(Native_capability const & c)
|
||||
{
|
||||
Object_pool<Pager_object>::Entry::cap(c);
|
||||
}
|
||||
|
||||
|
||||
Pager_object::Pager_object(unsigned const badge, Affinity::Location)
|
||||
:
|
||||
_signal_valid(0),
|
||||
_badge(badge)
|
||||
{ }
|
||||
|
||||
@@ -124,7 +106,12 @@ Native_capability Pager_activation_base::cap()
|
||||
** Pager_entrypoint **
|
||||
**********************/
|
||||
|
||||
void Pager_entrypoint::dissolve(Pager_object * const o) { remove_locked(o); }
|
||||
void Pager_entrypoint::dissolve(Pager_object * const o)
|
||||
{
|
||||
remove_locked(o);
|
||||
o->stop_paging();
|
||||
_activation->Signal_receiver::dissolve(o);
|
||||
}
|
||||
|
||||
|
||||
Pager_entrypoint::Pager_entrypoint(Cap_session *,
|
||||
@@ -138,11 +125,10 @@ Pager_entrypoint::Pager_entrypoint(Cap_session *,
|
||||
|
||||
Pager_capability Pager_entrypoint::manage(Pager_object * const o)
|
||||
{
|
||||
if (!_activation) return Pager_capability();
|
||||
o->_signal_context_cap = _activation->Signal_receiver::manage(o);
|
||||
unsigned const dst = _activation->cap().dst();
|
||||
Native_capability c = Native_capability(dst, o->badge());
|
||||
o->cap(c);
|
||||
unsigned const d = _activation->cap().dst();
|
||||
unsigned const b = o->badge();
|
||||
auto const p = reinterpret_cap_cast<Pager_object>(Native_capability(d, b));
|
||||
o->start_paging(_activation->Signal_receiver::manage(o), p);
|
||||
insert(o);
|
||||
return reinterpret_cap_cast<Pager_object>(c);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
#ifndef _PLACEMENT_NEW_H_
|
||||
#define _PLACEMENT_NEW_H_
|
||||
|
||||
/**
|
||||
* Placement new operator
|
||||
*/
|
||||
inline void *operator new(Genode::size_t, void *at) { return at; }
|
||||
/* base includes */
|
||||
#include <unmanaged_singleton.h>
|
||||
|
||||
/* FIXME: remove this header as soon as the Placeable template is public */
|
||||
|
||||
#endif /* _PLACEMENT_NEW_H_ */
|
||||
|
||||
@@ -123,6 +123,9 @@ void Signal_receiver::_platform_destructor()
|
||||
|
||||
void Signal_receiver::_unsynchronized_dissolve(Signal_context * const c)
|
||||
{
|
||||
/* wait untill all context references disappear and put context to sleep */
|
||||
Kernel::kill_signal_context(c->_cap.dst());
|
||||
|
||||
/* release server resources of context */
|
||||
signal_connection()->free_context(c->_cap);
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* \brief Helper for creating singleton objects
|
||||
* \author Norman Feske
|
||||
* \date 2013-05-14
|
||||
*
|
||||
* Before enabling the MMU on ARM, the 'cmpxchg' implementation is not always
|
||||
* guaranteed to work. For example, on the Raspberry Pi, the 'ldrex' as used by
|
||||
* 'cmpxchg' causes the machine to reboot. After enabling the MMU, everything
|
||||
* is fine. Hence, we need to avoid executing 'cmpxchg' prior this point.
|
||||
* Unfortunately, 'cmpxchg' is implicitly called each time when creating a
|
||||
* singleton object via a local-static object pattern. In this case, the
|
||||
* compiler generates code that calls the '__cxa_guard_acquire' function of the
|
||||
* C++ runtime, which, in turn, relies 'cmpxchg' for synchronization.
|
||||
*
|
||||
* The utility provided herein is an alternative way to create single object
|
||||
* instances without implicitly calling 'cmpxchg'. Because object creation is
|
||||
* not synchronized via a spin lock, it must not be used in scenarios where
|
||||
* multiple threads may contend.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _SINGLETON_H_
|
||||
#define _SINGLETON_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
|
||||
/* base-hw includes */
|
||||
#include <placement_new.h>
|
||||
|
||||
template <typename T, int ALIGN = 2, typename... Args>
|
||||
static inline T *unsynchronized_singleton(Args... args)
|
||||
{
|
||||
/*
|
||||
* Each instantiation of the function template with a different type 'T'
|
||||
* yields a dedicated instance of the local static variables, thereby
|
||||
* creating the living space for the singleton objects.
|
||||
*/
|
||||
static bool initialized;
|
||||
static int inst[sizeof(T)/sizeof(int) + 1] __attribute__((aligned(ALIGN)));
|
||||
|
||||
/* execute constructor on first call */
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
new (&inst) T(args...);
|
||||
}
|
||||
return reinterpret_cast<T *>(inst);
|
||||
}
|
||||
|
||||
#endif /* _SINGLETON_H_ */
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* \brief Thread bootstrap code
|
||||
* \author Christian Prochaska
|
||||
* \brief Thread initialization
|
||||
* \author Martin stein
|
||||
* \date 2013-02-15
|
||||
*/
|
||||
|
||||
@@ -13,13 +13,83 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/env.h>
|
||||
|
||||
/* base-hw includes */
|
||||
#include <kernel/interface.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
void Genode::Thread_base::_thread_bootstrap()
|
||||
Ram_dataspace_capability _main_thread_utcb_ds;
|
||||
|
||||
Native_thread_id _main_thread_id;
|
||||
|
||||
namespace Genode { Rm_session * env_context_area_rm_session(); }
|
||||
|
||||
|
||||
/**************************
|
||||
** Native types support **
|
||||
**************************/
|
||||
|
||||
Native_thread_id Genode::thread_get_my_native_id()
|
||||
{
|
||||
Thread_base * const t = Thread_base::myself();
|
||||
return t ? t->tid().thread_id : _main_thread_id;
|
||||
}
|
||||
|
||||
|
||||
/*****************************
|
||||
** Startup library support **
|
||||
*****************************/
|
||||
|
||||
void prepare_init_main_thread()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/*
|
||||
* Make data from the startup info persistantly available by copying it
|
||||
* before the UTCB gets polluted by the following function calls.
|
||||
*/
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
_main_thread_id = utcb->start_info()->thread_id();
|
||||
_main_thread_utcb_ds =
|
||||
reinterpret_cap_cast<Ram_dataspace>(utcb->start_info()->utcb_ds());
|
||||
}
|
||||
|
||||
|
||||
void prepare_reinit_main_thread() { prepare_init_main_thread(); }
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
void Thread_base::_thread_bootstrap()
|
||||
{
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
_tid.thread_id = utcb->startup_msg.thread_id();
|
||||
_tid.thread_id = utcb->start_info()->thread_id();
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread(Type type)
|
||||
{
|
||||
/* nothing platform specific to do if this is not a special thread */
|
||||
if (type == NORMAL) { return; }
|
||||
|
||||
/* if we got reinitialized we have to get rid of the old UTCB */
|
||||
size_t const utcb_size = sizeof(Native_utcb);
|
||||
addr_t const context_area = Native_config::context_area_virtual_base();
|
||||
addr_t const utcb_new = (addr_t)&_context->utcb - context_area;
|
||||
Rm_session * const rm = env_context_area_rm_session();
|
||||
if (type == REINITIALIZED_MAIN) { rm->detach(utcb_new); }
|
||||
|
||||
/* remap initial main-thread UTCB according to context-area spec */
|
||||
try { rm->attach_at(_main_thread_utcb_ds, utcb_new, utcb_size); }
|
||||
catch(...) {
|
||||
PERR("failed to re-map UTCB");
|
||||
while (1) ;
|
||||
}
|
||||
/* adjust initial object state in case of a main thread */
|
||||
tid().thread_id = _main_thread_id;
|
||||
_thread_cap = env()->parent()->main_thread_cap();
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern Native_utcb * __initial_sp;
|
||||
|
||||
namespace Genode { Rm_session * env_context_area_rm_session(); }
|
||||
|
||||
|
||||
@@ -28,13 +26,10 @@ namespace Genode { Rm_session * env_context_area_rm_session(); }
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
Native_utcb * Thread_base::utcb()
|
||||
{
|
||||
if (this) { return &_context->utcb; }
|
||||
return __initial_sp;
|
||||
return main_thread_utcb();
|
||||
}
|
||||
|
||||
|
||||
@@ -92,9 +87,7 @@ void Thread_base::start()
|
||||
sleep_forever();
|
||||
}
|
||||
/* start thread with its initial IP and aligned SP */
|
||||
addr_t thread_sp = (addr_t)&_context->stack[-4];
|
||||
thread_sp &= ~0xf;
|
||||
env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, thread_sp);
|
||||
env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, _context->stack_top());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -60,11 +60,6 @@
|
||||
/* catch erroneous kernel return */
|
||||
3: b 3b
|
||||
|
||||
/* handle for dynamic symbol objects */
|
||||
.align 3
|
||||
.global __dso_handle
|
||||
__dso_handle: .long 0
|
||||
|
||||
.section .bss
|
||||
|
||||
/* kernel stack */
|
||||
|
||||
@@ -10,6 +10,7 @@ REQUIRES += platform_arndale
|
||||
|
||||
# add include paths
|
||||
INC_DIR += $(REP_DIR)/src/core/arndale
|
||||
INC_DIR += $(REP_DIR)/src/core/exynos5
|
||||
INC_DIR += $(REP_DIR)/src/core/arm
|
||||
|
||||
# add C++ sources
|
||||
|
||||
@@ -240,55 +240,49 @@ void Arm::Cpu::flush_data_caches()
|
||||
* with more beauty.
|
||||
*/
|
||||
asm volatile (
|
||||
"mrc p15, 1, r0, c0, c0, 1\n" /* read CLIDR into R0 */
|
||||
"mrc p15, 1, r0, c0, c0, 1\n" /* read CLIDR into R0 */
|
||||
"ands r3, r0, #0x7000000\n"
|
||||
"mov r3, r3, lsr #23\n" /* cache level value (naturally aligned) */
|
||||
"mov r3, r3, lsr #23\n" /* cache level value (naturally aligned) */
|
||||
"beq 5f\n"
|
||||
"mov r10, #0\n"
|
||||
"mov r9, #0\n"
|
||||
|
||||
"1:\n"
|
||||
|
||||
"add r2, r10, r10, lsr #1\n" /* work out 3 x cachelevel */
|
||||
"mov r1, r0, lsr r2\n" /* bottom 3 bits are the Cache type for this level */
|
||||
"and r1, r1, #7\n" /* get those 3 bits alone */
|
||||
"add r2, r9, r9, lsr #1\n" /* work out 3 x cachelevel */
|
||||
"mov r1, r0, lsr r2\n" /* bottom 3 bits are the Cache type for this level */
|
||||
"and r1, r1, #7\n" /* get those 3 bits alone */
|
||||
"cmp r1, #2\n"
|
||||
"blt 4f\n" /* no cache or only instruction cache at this level */
|
||||
"mcr p15, 2, r10, c0, c0, 0\n" /* write CSSELR from R10 */
|
||||
"isb\n" /* ISB to sync the change to the CCSIDR */
|
||||
"mrc p15, 1, r1, c0, c0, 0\n" /* read current CCSIDR to R1 */
|
||||
"and r2, r1, #0x7\n" /* extract the line length field */
|
||||
"add r2, r2, #4\n" /* add 4 for the line length offset (log2 16 bytes) */
|
||||
"blt 4f\n" /* no cache or only instruction cache at this level */
|
||||
"mcr p15, 2, r9, c0, c0, 0\n" /* write CSSELR from R9 */
|
||||
"isb\n" /* ISB to sync the change to the CCSIDR */
|
||||
"mrc p15, 1, r1, c0, c0, 0\n" /* read current CCSIDR to R1 */
|
||||
"and r2, r1, #0x7\n" /* extract the line length field */
|
||||
"add r2, r2, #4\n" /* add 4 for the line length offset (log2 16 bytes) */
|
||||
"ldr r4, =0x3ff\n"
|
||||
"ands r4, r4, r1, lsr #3\n" /* R4 is the max number on the way size (right aligned) */
|
||||
"clz r5, r4\n" /* R5 is the bit position of the way size increment */
|
||||
"mov r9, r4\n" /* R9 working copy of the max way size (right aligned) */
|
||||
"ands r4, r4, r1, lsr #3\n" /* R4 is the max number on the way size (right aligned) */
|
||||
"clz r5, r4\n" /* R5 is the bit position of the way size increment */
|
||||
"mov r8, r4\n" /* R8 working copy of the max way size (right aligned) */
|
||||
|
||||
"2:\n"
|
||||
|
||||
"ldr r7, =0x00007fff\n"
|
||||
"ands r7, r7, r1, lsr #13\n" /* R7 is the max number of the index size (right aligned) */
|
||||
"ands r7, r7, r1, lsr #13\n" /* R7 is the max number of the index size (right aligned) */
|
||||
|
||||
"3:\n"
|
||||
|
||||
"orr r11, r10, r9, lsl r5\n" /* factor in the way number and cache number into R11 */
|
||||
"orr r11, r11, r7, lsl r2\n" /* factor in the index number */
|
||||
"mcr p15, 0, r11, c7, c10, 2\n" /* DCCSW, clean by set/way */
|
||||
"subs r7, r7, #1\n" /* decrement the index */
|
||||
"orr r6, r9, r8, lsl r5\n" /* factor in the way number and cache number into R11 */
|
||||
"orr r6, r6, r7, lsl r2\n" /* factor in the index number */
|
||||
"mcr p15, 0, r6, c7, c10, 2\n" /* DCCSW, clean by set/way */
|
||||
"subs r7, r7, #1\n" /* decrement the index */
|
||||
"bge 3b\n"
|
||||
"subs r9, r9, #1\n" /* decrement the way number */
|
||||
"subs r8, r8, #1\n" /* decrement the way number */
|
||||
"bge 2b\n"
|
||||
|
||||
"4:\n"
|
||||
|
||||
"add r10, r10, #2\n" /* increment the cache number */
|
||||
"cmp r3, r10\n"
|
||||
"add r9, r9, #2\n" /* increment the cache number */
|
||||
"cmp r3, r9\n"
|
||||
"bgt 1b\n"
|
||||
"dsb\n"
|
||||
|
||||
"5:\n"
|
||||
|
||||
::: "r0", "r1", "r2", "r3", "r4",
|
||||
"r5", "r7", "r9", "r10", "r11");
|
||||
::: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _ARNDALE__CPU_H_
|
||||
#define _ARNDALE__CPU_H_
|
||||
#ifndef _EXYNOS5__CPU_H_
|
||||
#define _EXYNOS5__CPU_H_
|
||||
|
||||
/* core includes */
|
||||
#include <cpu/cortex_a15.h>
|
||||
@@ -25,5 +25,5 @@ namespace Genode
|
||||
class Cpu : public Cortex_a15::Cpu { };
|
||||
}
|
||||
|
||||
#endif /* _ARNDALE__CPU_H_ */
|
||||
#endif /* _EXYNOS5__CPU_H_ */
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _ARNDALE__PIC_H_
|
||||
#define _ARNDALE__PIC_H_
|
||||
#ifndef _EXYNOS5__PIC_H_
|
||||
#define _EXYNOS5__PIC_H_
|
||||
|
||||
/* core includes */
|
||||
#include <pic/corelink_gic400.h>
|
||||
@@ -38,5 +38,5 @@ namespace Kernel
|
||||
bool Arm_gic::Pic::_use_security_ext() { return 0; }
|
||||
|
||||
|
||||
#endif /* _ARNDALE__PIC_H_ */
|
||||
#endif /* _EXYNOS5__PIC_H_ */
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _ARNDALE__TIMER_H_
|
||||
#define _ARNDALE__TIMER_H_
|
||||
#ifndef _EXYNOS5__TIMER_H_
|
||||
#define _EXYNOS5__TIMER_H_
|
||||
|
||||
/* core includes */
|
||||
#include <board.h>
|
||||
@@ -37,5 +37,4 @@ namespace Kernel
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _ARNDALE__TIMER_H_ */
|
||||
|
||||
#endif /* _EXYNOS5__TIMER_H_ */
|
||||
@@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _ARNDALE__TLB_H_
|
||||
#define _ARNDALE__TLB_H_
|
||||
#ifndef _EXYNOS5__TLB_H_
|
||||
#define _EXYNOS5__TLB_H_
|
||||
|
||||
/* core includes */
|
||||
#include <board.h>
|
||||
@@ -43,5 +43,5 @@ namespace Genode
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _ARNDALE__TLB_H_ */
|
||||
#endif /* _EXYNOS5__TLB_H_ */
|
||||
|
||||
@@ -41,8 +41,8 @@ namespace Genode
|
||||
{
|
||||
enum {
|
||||
SECURE_UNLOCKED,
|
||||
SECURE_LOCKED,
|
||||
UNSECURE_UNLOCKED,
|
||||
SECURE_LOCKED,
|
||||
UNSECURE_LOCKED
|
||||
};
|
||||
|
||||
@@ -123,10 +123,10 @@ namespace Genode
|
||||
write<Csl19::Slave_a>(Csl00::UNSECURE);
|
||||
|
||||
/* GPIO */
|
||||
//write<Csl00::Slave_b>(Csl00::UNSECURE);
|
||||
//write<Csl01::Slave_a>(Csl00::UNSECURE);
|
||||
//write<Csl01::Slave_b>(Csl00::UNSECURE);
|
||||
//write<Csl02::Slave_a>(Csl00::UNSECURE);
|
||||
write<Csl00::Slave_b>(Csl00::SECURE);
|
||||
write<Csl01::Slave_a>(Csl00::SECURE);
|
||||
write<Csl01::Slave_b>(Csl00::SECURE);
|
||||
write<Csl02::Slave_a>(Csl00::SECURE);
|
||||
|
||||
/* IOMUXC TODO */
|
||||
write<Csl05::Slave_a>(Csl00::UNSECURE);
|
||||
@@ -138,15 +138,15 @@ namespace Genode
|
||||
write<Csl00::Slave_a>(Csl00::UNSECURE);
|
||||
|
||||
/* TVE */
|
||||
//write<Csl22::Slave_b>(Csl00::UNSECURE);
|
||||
write<Csl22::Slave_b>(Csl00::SECURE);
|
||||
|
||||
/* I2C */
|
||||
//write<Csl18::Slave_a>(Csl00::UNSECURE);
|
||||
//write<Csl17::Slave_b>(Csl00::UNSECURE);
|
||||
//write<Csl31::Slave_a>(Csl00::UNSECURE);
|
||||
write<Csl18::Slave_a>(Csl00::SECURE);
|
||||
write<Csl17::Slave_b>(Csl00::SECURE);
|
||||
write<Csl31::Slave_a>(Csl00::SECURE);
|
||||
|
||||
/* IPU */
|
||||
//write<Csl24::Slave_a>(Csl00::UNSECURE);
|
||||
write<Csl24::Slave_a>(Csl00::SECURE);
|
||||
|
||||
/* Audio */
|
||||
write<Csl18::Slave_b>(Csl00::UNSECURE);
|
||||
@@ -167,10 +167,10 @@ namespace Genode
|
||||
write<Csl29::Slave_a>(Csl00::UNSECURE);
|
||||
|
||||
/* GPU 2D */
|
||||
write<Csl24::Slave_b>(Csl00::UNSECURE);
|
||||
write<Csl24::Slave_b>(Csl00::SECURE);
|
||||
|
||||
/* GPU 3D */
|
||||
write<Csl27::Slave_b>(Csl00::UNSECURE);
|
||||
write<Csl27::Slave_b>(Csl00::SECURE);
|
||||
|
||||
write<Csl02::Slave_b>(Csl00::UNSECURE);
|
||||
write<Csl03::Slave_a>(Csl00::UNSECURE);
|
||||
@@ -196,7 +196,7 @@ namespace Genode
|
||||
write<Csl20::Slave_b>(Csl00::UNSECURE);
|
||||
write<Csl21::Slave_a>(Csl00::UNSECURE);
|
||||
write<Csl21::Slave_b>(Csl00::UNSECURE);
|
||||
//write<Csl23::Slave_a>(Csl00::UNSECURE); //VPU
|
||||
write<Csl23::Slave_a>(Csl00::SECURE); //VPU
|
||||
write<Csl23::Slave_b>(Csl00::UNSECURE);
|
||||
write<Csl26::Slave_b>(Csl00::UNSECURE);
|
||||
write<Csl27::Slave_a>(Csl00::UNSECURE);
|
||||
@@ -204,16 +204,19 @@ namespace Genode
|
||||
write<Csl30::Slave_a>(Csl00::UNSECURE);
|
||||
write<Csl31::Slave_b>(Csl00::UNSECURE);
|
||||
|
||||
/* DMA from graphical subsystem is considered to be secure */
|
||||
write<Master::Gpu>(Master::SECURE_UNLOCKED);
|
||||
|
||||
/* all other DMA operations are insecure */
|
||||
write<Master::Sdma>(Master::UNSECURE_UNLOCKED);
|
||||
write<Master::Esdhc3>(Master::UNSECURE_UNLOCKED);
|
||||
write<Master::Gpu>(Master::UNSECURE_UNLOCKED);
|
||||
write<Master::Usb>(Master::UNSECURE_UNLOCKED);
|
||||
write<Master::Pata>(Master::UNSECURE_UNLOCKED);
|
||||
write<Master::Esdhc4>(Master::UNSECURE_UNLOCKED);
|
||||
write<Master::Fec>(Master::UNSECURE_UNLOCKED);
|
||||
write<Master::Dap>(Master::UNSECURE_UNLOCKED);
|
||||
write<Master::Esdhc1>(Master::UNSECURE_UNLOCKED);
|
||||
write<Master::Esdhc2>(Master::UNSECURE_UNLOCKED);
|
||||
write<Master::Esdhc3>(Master::UNSECURE_UNLOCKED);
|
||||
write<Master::Esdhc4>(Master::UNSECURE_UNLOCKED);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -50,18 +50,19 @@ namespace Genode
|
||||
_alloc->free(addr, size); }
|
||||
|
||||
size_t consumed() {
|
||||
PDBG("Unexprected call");
|
||||
PDBG("Unexpected call");
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t overhead(size_t size) {
|
||||
PDBG("Unexprected call");
|
||||
PDBG("Unexpected call");
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool need_size_for_free() const { return true; }
|
||||
bool need_size_for_free() const override {
|
||||
return _alloc->need_size_for_free(); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -41,8 +41,8 @@ namespace Genode {
|
||||
Phys_allocator _irq_alloc; /* IRQ allocator */
|
||||
Rom_fs _rom_fs; /* ROM file system */
|
||||
|
||||
addr_t _vm_base; /* base of virtual address space */
|
||||
size_t _vm_size; /* size of virtual address space */
|
||||
addr_t _vm_start; /* base of virtual address space */
|
||||
size_t _vm_size; /* size of virtual address space */
|
||||
|
||||
/**
|
||||
* Get one of the consecutively numbered available resource regions
|
||||
@@ -101,7 +101,7 @@ namespace Genode {
|
||||
|
||||
inline Range_allocator * irq_alloc() { return &_irq_alloc; }
|
||||
|
||||
inline addr_t vm_start() const { return _vm_base; }
|
||||
inline addr_t vm_start() const { return _vm_start; }
|
||||
|
||||
inline size_t vm_size() const { return _vm_size; }
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace Genode {
|
||||
|
||||
inline Range_allocator * region_alloc()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
Kernel::log() << __PRETTY_FUNCTION__ << "not implemented\n";
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__UTIL_H_
|
||||
#define _CORE__INCLUDE__UTIL_H_
|
||||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <rm_session/rm_session.h>
|
||||
@@ -20,7 +20,10 @@
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
enum { MIN_PAGE_SIZE_LOG2 = 12 };
|
||||
enum {
|
||||
ACTIVITY_TABLE_ON_FAULTS = 0,
|
||||
MIN_PAGE_SIZE_LOG2 = 12,
|
||||
};
|
||||
|
||||
/**
|
||||
* Identification that core threads use to get access to their metadata
|
||||
@@ -99,20 +102,41 @@ namespace Genode
|
||||
return 20;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Debug output on page faults
|
||||
* Print debug output on page faults
|
||||
*
|
||||
* \param fault_msg introductory message
|
||||
* \param fault_addr target address of the fault access
|
||||
* \param fault_ip instruction pointer of the faulter
|
||||
* \param fault_type access type of fault
|
||||
* \param faulter_badge user identification of faulter
|
||||
*/
|
||||
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
|
||||
Rm_session::Fault_type pf_type,
|
||||
unsigned faulter_badge)
|
||||
{
|
||||
printf("%s (%s pf_addr=%p pf_ip=%p from %02x)", msg,
|
||||
pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ",
|
||||
(void *)pf_addr, (void *)pf_ip,
|
||||
faulter_badge);
|
||||
inline void print_page_fault(char const * const fault_msg,
|
||||
addr_t const fault_addr,
|
||||
addr_t const fault_ip,
|
||||
Rm_session::Fault_type const fault_type,
|
||||
unsigned const faulter_badge);
|
||||
}
|
||||
|
||||
|
||||
void Genode::print_page_fault(char const * const fault_msg,
|
||||
addr_t const fault_addr,
|
||||
addr_t const fault_ip,
|
||||
Rm_session::Fault_type const fault_type,
|
||||
unsigned const faulter_badge)
|
||||
{
|
||||
const char read[] = "read from";
|
||||
const char write[] = "write to";
|
||||
printf("\033[31m%s\033[0m (faulter %x", fault_msg, faulter_badge);
|
||||
printf(" with IP %p attempts to", (void *)fault_ip);
|
||||
printf(" %s", fault_type == Rm_session::READ_FAULT ? read : write);
|
||||
printf(" address %p)\n", (void *)fault_addr);
|
||||
if (ACTIVITY_TABLE_ON_FAULTS) {
|
||||
printf("---------- activity table ----------\n");
|
||||
Kernel::print_char(0);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__UTIL_H_ */
|
||||
#endif /* _UTIL_H_ */
|
||||
|
||||
|
||||
@@ -30,11 +30,7 @@ namespace Kernel
|
||||
|
||||
class Kernel::Ipc_node
|
||||
{
|
||||
private:
|
||||
|
||||
class Message_buf;
|
||||
|
||||
typedef Genode::Fifo<Message_buf> Message_fifo;
|
||||
protected:
|
||||
|
||||
enum State
|
||||
{
|
||||
@@ -45,6 +41,12 @@ class Kernel::Ipc_node
|
||||
PREPARE_AND_AWAIT_REPLY = 5,
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
class Message_buf;
|
||||
|
||||
typedef Genode::Fifo<Message_buf> Message_fifo;
|
||||
|
||||
/**
|
||||
* Describes the buffer for incoming or outgoing messages
|
||||
*/
|
||||
@@ -201,6 +203,16 @@ class Kernel::Ipc_node
|
||||
*/
|
||||
virtual void _await_ipc_failed() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Ipc_node * outbuf_dst() { return _outbuf_dst; }
|
||||
|
||||
State state() { return _state; }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,14 +31,17 @@
|
||||
#include <timer.h>
|
||||
#include <pic.h>
|
||||
|
||||
/* base includes */
|
||||
#include <unmanaged_singleton.h>
|
||||
|
||||
/* base-hw includes */
|
||||
#include <singleton.h>
|
||||
#include <kernel/perf_counter.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
/* get core configuration */
|
||||
extern Genode::Native_utcb * _main_thread_utcb;
|
||||
extern Genode::Native_thread_id _main_thread_id;
|
||||
extern int _kernel_stack_high;
|
||||
extern "C" void CORE_MAIN();
|
||||
|
||||
@@ -47,7 +50,7 @@ namespace Kernel
|
||||
/**
|
||||
* Return interrupt-controller singleton
|
||||
*/
|
||||
Pic * pic() { return unsynchronized_singleton<Pic>(); }
|
||||
Pic * pic() { return unmanaged_singleton<Pic>(); }
|
||||
|
||||
/* import Genode types */
|
||||
typedef Genode::umword_t umword_t;
|
||||
@@ -64,15 +67,15 @@ namespace Kernel
|
||||
*/
|
||||
static void idle_main() { while (1) ; }
|
||||
|
||||
Pd_ids * pd_ids() { return unsynchronized_singleton<Pd_ids>(); }
|
||||
Thread_ids * thread_ids() { return unsynchronized_singleton<Thread_ids>(); }
|
||||
Signal_context_ids * signal_context_ids() { return unsynchronized_singleton<Signal_context_ids>(); }
|
||||
Signal_receiver_ids * signal_receiver_ids() { return unsynchronized_singleton<Signal_receiver_ids>(); }
|
||||
Pd_ids * pd_ids() { return unmanaged_singleton<Pd_ids>(); }
|
||||
Thread_ids * thread_ids() { return unmanaged_singleton<Thread_ids>(); }
|
||||
Signal_context_ids * signal_context_ids() { return unmanaged_singleton<Signal_context_ids>(); }
|
||||
Signal_receiver_ids * signal_receiver_ids() { return unmanaged_singleton<Signal_receiver_ids>(); }
|
||||
|
||||
Pd_pool * pd_pool() { return unsynchronized_singleton<Pd_pool>(); }
|
||||
Thread_pool * thread_pool() { return unsynchronized_singleton<Thread_pool>(); }
|
||||
Signal_context_pool * signal_context_pool() { return unsynchronized_singleton<Signal_context_pool>(); }
|
||||
Signal_receiver_pool * signal_receiver_pool() { return unsynchronized_singleton<Signal_receiver_pool>(); }
|
||||
Pd_pool * pd_pool() { return unmanaged_singleton<Pd_pool>(); }
|
||||
Thread_pool * thread_pool() { return unmanaged_singleton<Thread_pool>(); }
|
||||
Signal_context_pool * signal_context_pool() { return unmanaged_singleton<Signal_context_pool>(); }
|
||||
Signal_receiver_pool * signal_receiver_pool() { return unmanaged_singleton<Signal_receiver_pool>(); }
|
||||
|
||||
/**
|
||||
* Access to static kernel timer
|
||||
@@ -91,11 +94,25 @@ namespace Kernel
|
||||
*/
|
||||
static Pd * core()
|
||||
{
|
||||
constexpr int tlb_align = 1 << Core_tlb::ALIGNM_LOG2;
|
||||
/**
|
||||
* Core protection-domain
|
||||
*/
|
||||
class Core_pd : public Pd
|
||||
{
|
||||
public:
|
||||
|
||||
Core_tlb *core_tlb = unsynchronized_singleton<Core_tlb, tlb_align>();
|
||||
Pd *pd = unsynchronized_singleton<Pd>(core_tlb, nullptr);
|
||||
return pd;
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Core_pd(Tlb * const tlb, Platform_pd * const platform_pd)
|
||||
:
|
||||
Pd(tlb, platform_pd)
|
||||
{ }
|
||||
};
|
||||
constexpr int tlb_align = 1 << Core_tlb::ALIGNM_LOG2;
|
||||
Core_tlb * core_tlb = unmanaged_singleton<Core_tlb, tlb_align>();
|
||||
Core_pd * core_pd = unmanaged_singleton<Core_pd>(core_tlb, nullptr);
|
||||
return core_pd;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,8 +250,9 @@ extern "C" void kernel()
|
||||
/* start thread with stack pointer at the top of stack */
|
||||
static Native_utcb utcb;
|
||||
static Thread t(Priority::MAX, "core");
|
||||
_main_thread_id = t.id();
|
||||
_main_thread_utcb = &utcb;
|
||||
_main_thread_utcb->startup_msg.init(t.id());
|
||||
_main_thread_utcb->start_info()->init(t.id(), Genode::Native_capability());
|
||||
t.ip = (addr_t)CORE_MAIN;;
|
||||
t.sp = (addr_t)s + STACK_SIZE;
|
||||
t.init(0, core_id(), &utcb, 1);
|
||||
@@ -262,8 +280,8 @@ Kernel::Mode_transition_control * Kernel::mtc()
|
||||
sp = (addr_t)&_kernel_stack_high;
|
||||
core()->admit(this);
|
||||
}
|
||||
} * const k = unsynchronized_singleton<Kernel_context>();
|
||||
} * const k = unmanaged_singleton<Kernel_context>();
|
||||
|
||||
/* initialize mode transition page */
|
||||
return unsynchronized_singleton<Mode_transition_control>(k);
|
||||
return unmanaged_singleton<Mode_transition_control>(k);
|
||||
}
|
||||
|
||||
@@ -21,9 +21,6 @@
|
||||
/* core includes */
|
||||
#include <assert.h>
|
||||
|
||||
/* base-hw includes */
|
||||
#include <singleton.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
template <typename T> class Avl_tree : public Genode::Avl_tree<T> { };
|
||||
|
||||
@@ -289,6 +289,13 @@ class Kernel::Scheduler
|
||||
* Exclude 'i' from scheduling
|
||||
*/
|
||||
void remove(T * const i) { _items[i->priority()].remove(i); }
|
||||
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
T * idle() const { return _idle; }
|
||||
};
|
||||
|
||||
class Kernel::Execution_context : public Cpu_scheduler::Item
|
||||
|
||||
@@ -47,16 +47,6 @@ void Signal_context_killer::_cancel_waiting()
|
||||
}
|
||||
|
||||
|
||||
/****************************
|
||||
** Signal_receiver_killer **
|
||||
****************************/
|
||||
|
||||
void Signal_receiver_killer::_cancel_waiting()
|
||||
{
|
||||
if (_receiver) { _receiver->_killer_cancelled(); }
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
** Signal_context **
|
||||
********************/
|
||||
@@ -67,7 +57,11 @@ void Signal_context::_deliverable()
|
||||
}
|
||||
|
||||
|
||||
Signal_context::~Signal_context() { _receiver->_context_killed(this); }
|
||||
Signal_context::~Signal_context()
|
||||
{
|
||||
if (_killer) { _killer->_signal_context_kill_failed(); }
|
||||
_receiver->_context_destructed(this);
|
||||
}
|
||||
|
||||
|
||||
Signal_context::Signal_context(Signal_receiver * const r, unsigned const imprint)
|
||||
@@ -78,9 +72,9 @@ Signal_context::Signal_context(Signal_receiver * const r, unsigned const imprint
|
||||
_imprint(imprint),
|
||||
_submits(0),
|
||||
_ack(1),
|
||||
_kill(0),
|
||||
_killed(0),
|
||||
_killer(0),
|
||||
_ack_handler(&_default_ack_handler)
|
||||
{
|
||||
if (r->_add_context(this)) { throw Assign_to_receiver_failed(); }
|
||||
r->_add_context(this);
|
||||
}
|
||||
|
||||
@@ -39,11 +39,6 @@ namespace Kernel
|
||||
*/
|
||||
class Signal_context_killer;
|
||||
|
||||
/**
|
||||
* Ability to destruct signal receivers
|
||||
*/
|
||||
class Signal_receiver_killer;
|
||||
|
||||
/**
|
||||
* Signal types that are assigned to a signal receiver each
|
||||
*/
|
||||
@@ -69,7 +64,9 @@ class Kernel::Signal_ack_handler
|
||||
{
|
||||
friend class Signal_context;
|
||||
|
||||
Signal_context * _signal_context;
|
||||
private:
|
||||
|
||||
Signal_context * _signal_context;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -120,6 +117,14 @@ class Kernel::Signal_handler
|
||||
*/
|
||||
virtual void _receive_signal(void * const base, size_t const size) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Signal_receiver * receiver() const { return _receiver; }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@@ -151,20 +156,33 @@ class Kernel::Signal_context_killer
|
||||
Signal_context * _context;
|
||||
|
||||
/**
|
||||
* Backend for for destructor and cancel_waiting
|
||||
* Backend for destructor and cancel_waiting
|
||||
*/
|
||||
void _cancel_waiting();
|
||||
|
||||
/**
|
||||
* Notice that the destruction is pending
|
||||
* Notice that the kill operation is pending
|
||||
*/
|
||||
virtual void _signal_context_kill_pending() = 0;
|
||||
|
||||
/**
|
||||
* Notice that pending destruction is done
|
||||
* Notice that pending kill operation is done
|
||||
*/
|
||||
virtual void _signal_context_kill_done() = 0;
|
||||
|
||||
/**
|
||||
* Notice that pending kill operation failed
|
||||
*/
|
||||
virtual void _signal_context_kill_failed() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Signal_context * context() const { return _context; }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@@ -183,47 +201,6 @@ class Kernel::Signal_context_killer
|
||||
void cancel_waiting() { _cancel_waiting(); }
|
||||
};
|
||||
|
||||
class Kernel::Signal_receiver_killer
|
||||
{
|
||||
friend class Signal_receiver;
|
||||
|
||||
private:
|
||||
|
||||
Signal_receiver * _receiver;
|
||||
|
||||
/**
|
||||
* Backend for for destructor and cancel_waiting
|
||||
*/
|
||||
void _cancel_waiting();
|
||||
|
||||
/**
|
||||
* Notice that the destruction is pending
|
||||
*/
|
||||
virtual void _signal_receiver_kill_pending() = 0;
|
||||
|
||||
/**
|
||||
* Notice that pending destruction is done
|
||||
*/
|
||||
virtual void _signal_receiver_kill_done() = 0;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Signal_receiver_killer() : _receiver(0) { }
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~Signal_receiver_killer() { _cancel_waiting(); }
|
||||
|
||||
/**
|
||||
* Stop waiting for a signal receiver
|
||||
*/
|
||||
void cancel_waiting() { _cancel_waiting(); }
|
||||
};
|
||||
|
||||
class Kernel::Signal_context
|
||||
:
|
||||
public Object<Signal_context, MAX_SIGNAL_CONTEXTS,
|
||||
@@ -256,7 +233,7 @@ class Kernel::Signal_context
|
||||
unsigned const _imprint;
|
||||
unsigned _submits;
|
||||
bool _ack;
|
||||
bool _kill;
|
||||
bool _killed;
|
||||
Signal_context_killer * _killer;
|
||||
Default_ack_handler _default_ack_handler;
|
||||
Signal_ack_handler * _ack_handler;
|
||||
@@ -276,24 +253,17 @@ class Kernel::Signal_context
|
||||
}
|
||||
|
||||
/**
|
||||
* Notice that the killer of the context has been destructed
|
||||
* Notice that the killer of the context has cancelled waiting
|
||||
*/
|
||||
void _killer_cancelled() { _killer = 0; }
|
||||
|
||||
protected:
|
||||
public:
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Signal_context();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Exception types
|
||||
*/
|
||||
struct Assign_to_receiver_failed { };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -325,7 +295,7 @@ class Kernel::Signal_context
|
||||
*/
|
||||
int submit(unsigned const n)
|
||||
{
|
||||
if (_kill || _submits >= (unsigned)~0 - n) { return -1; }
|
||||
if (_killed || _submits >= (unsigned)~0 - n) { return -1; }
|
||||
_submits += n;
|
||||
if (_ack) { _deliverable(); }
|
||||
return 0;
|
||||
@@ -338,15 +308,15 @@ class Kernel::Signal_context
|
||||
{
|
||||
_ack_handler->_signal_acknowledged();
|
||||
if (_ack) { return; }
|
||||
if (!_kill) {
|
||||
if (!_killed) {
|
||||
_ack = 1;
|
||||
_deliverable();
|
||||
return;
|
||||
}
|
||||
this->~Signal_context();
|
||||
if (_killer) {
|
||||
_killer->_context = 0;
|
||||
_killer->_signal_context_kill_done();
|
||||
_killer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,16 +330,19 @@ class Kernel::Signal_context
|
||||
*/
|
||||
int kill(Signal_context_killer * const k)
|
||||
{
|
||||
if (_kill) { return -1; }
|
||||
|
||||
/* destruct directly if there is no unacknowledged delivery */
|
||||
/* check if in a kill operation or already killed */
|
||||
if (_killed) {
|
||||
if (_ack) { return 0; }
|
||||
return -1;
|
||||
}
|
||||
/* kill directly if there is no unacknowledged delivery */
|
||||
if (_ack) {
|
||||
this->~Signal_context();
|
||||
_killed = 1;
|
||||
return 0;
|
||||
}
|
||||
/* wait for delivery acknowledgement */
|
||||
_killer = k;
|
||||
_kill = 1;
|
||||
_killer = k;
|
||||
_killed = 1;
|
||||
_killer->_context = this;
|
||||
_killer->_signal_context_kill_pending();
|
||||
return 0;
|
||||
@@ -380,12 +353,10 @@ class Kernel::Signal_receiver
|
||||
:
|
||||
public Object<Signal_receiver, MAX_SIGNAL_RECEIVERS,
|
||||
Signal_receiver_ids, signal_receiver_ids,
|
||||
signal_receiver_pool>,
|
||||
public Signal_context_killer
|
||||
signal_receiver_pool>
|
||||
{
|
||||
friend class Signal_context;
|
||||
friend class Signal_handler;
|
||||
friend class Signal_receiver_killer;
|
||||
|
||||
private:
|
||||
|
||||
@@ -396,9 +367,6 @@ class Kernel::Signal_receiver
|
||||
Fifo<Signal_handler::Fifo_element> _handlers;
|
||||
Fifo<Signal_context::Fifo_element> _deliver;
|
||||
Fifo<Signal_context::Fifo_element> _contexts;
|
||||
bool _kill;
|
||||
Signal_receiver_killer * _killer;
|
||||
unsigned _context_kills;
|
||||
|
||||
/**
|
||||
* Recognize that context 'c' has submits to deliver
|
||||
@@ -438,22 +406,17 @@ class Kernel::Signal_receiver
|
||||
}
|
||||
|
||||
/**
|
||||
* Notice that a context of the receiver has been killed
|
||||
* Notice that a context of the receiver has been destructed
|
||||
*
|
||||
* \param c killed context
|
||||
* \param c destructed context
|
||||
*/
|
||||
void _context_killed(Signal_context * const c)
|
||||
void _context_destructed(Signal_context * const c)
|
||||
{
|
||||
_contexts.remove(&c->_contexts_fe);
|
||||
if (!c->_deliver_fe.is_enqueued()) { return; }
|
||||
_deliver.remove(&c->_deliver_fe);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notice that the killer of the receiver has cancelled waiting
|
||||
*/
|
||||
void _killer_cancelled() { _killer = 0; }
|
||||
|
||||
/**
|
||||
* Notice that handler 'h' has cancelled waiting
|
||||
*/
|
||||
@@ -464,47 +427,24 @@ class Kernel::Signal_receiver
|
||||
|
||||
/**
|
||||
* Assign context 'c' to the receiver
|
||||
*
|
||||
* \retval 0 succeeded
|
||||
* \retval -1 failed
|
||||
*/
|
||||
int _add_context(Signal_context * const c)
|
||||
void _add_context(Signal_context * const c)
|
||||
{
|
||||
if (_kill) { return -1; }
|
||||
_contexts.enqueue(&c->_contexts_fe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
** Signal_context_killer **
|
||||
***************************/
|
||||
|
||||
void _signal_context_kill_pending() { _context_kills++; }
|
||||
|
||||
void _signal_context_kill_done()
|
||||
{
|
||||
_context_kills--;
|
||||
if (!_context_kills && _kill) {
|
||||
this->~Signal_receiver();
|
||||
if (_killer) {
|
||||
_killer->_receiver = 0;
|
||||
_killer->_signal_receiver_kill_done();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Destructor
|
||||
*/
|
||||
Signal_receiver()
|
||||
:
|
||||
_kill(0),
|
||||
_killer(0),
|
||||
_context_kills(0)
|
||||
{ }
|
||||
~Signal_receiver()
|
||||
{
|
||||
/* destruct all attached contexts */
|
||||
while (Signal_context * c = _contexts.dequeue()->object()) {
|
||||
c->~Signal_context();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Let a handler 'h' wait for signals of the receiver
|
||||
@@ -514,7 +454,7 @@ class Kernel::Signal_receiver
|
||||
*/
|
||||
int add_handler(Signal_handler * const h)
|
||||
{
|
||||
if (_kill || h->_receiver) { return -1; }
|
||||
if (h->_receiver) { return -1; }
|
||||
_handlers.enqueue(&h->_handlers_fe);
|
||||
h->_receiver = this;
|
||||
h->_await_signal(this);
|
||||
@@ -526,37 +466,6 @@ class Kernel::Signal_receiver
|
||||
* Return wether any of the contexts of this receiver is deliverable
|
||||
*/
|
||||
bool deliverable() { return !_deliver.empty(); }
|
||||
|
||||
/**
|
||||
* Destruct receiver or prepare to do it as soon as delivery is done
|
||||
*
|
||||
* \param killer object that shall receive progress reports
|
||||
*
|
||||
* \retval 0 succeeded
|
||||
* \retval -1 failed
|
||||
*/
|
||||
int kill(Signal_receiver_killer * const k)
|
||||
{
|
||||
if (_kill) { return -1; }
|
||||
|
||||
/* start killing at all contexts of the receiver */
|
||||
Signal_context * c = _contexts.dequeue()->object();
|
||||
while (c) {
|
||||
c->kill(this);
|
||||
c = _contexts.dequeue()->object();
|
||||
}
|
||||
/* destruct directly if no context kill is pending */
|
||||
if (!_context_kills) {
|
||||
this->~Signal_receiver();
|
||||
return 0;
|
||||
}
|
||||
/* wait for pending context kills */
|
||||
_kill = 1;
|
||||
_killer = k;
|
||||
_killer->_receiver = this;
|
||||
_killer->_signal_receiver_kill_pending();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _KERNEL__SIGNAL_RECEIVER_ */
|
||||
|
||||
@@ -48,18 +48,10 @@ void Thread::_signal_context_kill_done()
|
||||
}
|
||||
|
||||
|
||||
void Thread::_signal_receiver_kill_pending()
|
||||
void Thread::_signal_context_kill_failed()
|
||||
{
|
||||
assert(_state == SCHEDULED);
|
||||
_state = AWAITS_SIGNAL_RECEIVER_KILL;
|
||||
cpu_scheduler()->remove(this);
|
||||
}
|
||||
|
||||
|
||||
void Thread::_signal_receiver_kill_done()
|
||||
{
|
||||
assert(_state == AWAITS_SIGNAL_RECEIVER_KILL);
|
||||
user_arg_0(0);
|
||||
assert(_state == AWAITS_SIGNAL_CONTEXT_KILL);
|
||||
user_arg_0(-1);
|
||||
_schedule();
|
||||
}
|
||||
|
||||
@@ -84,6 +76,7 @@ void Thread::_received_ipc_request(size_t const s)
|
||||
{
|
||||
switch (_state) {
|
||||
case SCHEDULED:
|
||||
user_arg_0(0);
|
||||
return;
|
||||
default:
|
||||
PERR("wrong thread state to receive IPC");
|
||||
@@ -112,6 +105,7 @@ void Thread::_await_ipc_succeeded(size_t const s)
|
||||
{
|
||||
switch (_state) {
|
||||
case AWAITS_IPC:
|
||||
user_arg_0(0);
|
||||
_schedule();
|
||||
return;
|
||||
default:
|
||||
@@ -126,12 +120,9 @@ void Thread::_await_ipc_failed()
|
||||
{
|
||||
switch (_state) {
|
||||
case AWAITS_IPC:
|
||||
user_arg_0(-1);
|
||||
_schedule();
|
||||
return;
|
||||
case SCHEDULED:
|
||||
PERR("failed to receive IPC");
|
||||
_stop();
|
||||
return;
|
||||
default:
|
||||
PERR("wrong thread state to cancel IPC");
|
||||
_stop();
|
||||
@@ -157,9 +148,6 @@ int Thread::_resume()
|
||||
case AWAITS_SIGNAL_CONTEXT_KILL:
|
||||
Signal_context_killer::cancel_waiting();
|
||||
return 0;
|
||||
case AWAITS_SIGNAL_RECEIVER_KILL:
|
||||
Signal_receiver_killer::cancel_waiting();
|
||||
return 0;
|
||||
case AWAITS_START:
|
||||
case STOPPED:;
|
||||
}
|
||||
@@ -294,7 +282,7 @@ void Thread::_call_new_pd()
|
||||
}
|
||||
|
||||
|
||||
void Thread::_call_kill_pd()
|
||||
void Thread::_call_bin_pd()
|
||||
{
|
||||
/* check permissions */
|
||||
if (!_core()) {
|
||||
@@ -338,7 +326,7 @@ void Thread::_call_new_thread()
|
||||
}
|
||||
|
||||
|
||||
void Thread::_call_kill_thread()
|
||||
void Thread::_call_bin_thread()
|
||||
{
|
||||
/* check permissions */
|
||||
assert(_core());
|
||||
@@ -449,16 +437,16 @@ void Thread::_call_yield_thread()
|
||||
}
|
||||
|
||||
|
||||
void Thread::_call_wait_for_request()
|
||||
void Thread::_call_await_request_msg()
|
||||
{
|
||||
void * buf_base;
|
||||
size_t buf_size;
|
||||
_utcb_phys->call_wait_for_request(buf_base, buf_size);
|
||||
_utcb_phys->message()->info_about_await_request(buf_base, buf_size);
|
||||
Ipc_node::await_request(buf_base, buf_size);
|
||||
}
|
||||
|
||||
|
||||
void Thread::_call_request_and_wait()
|
||||
void Thread::_call_send_request_msg()
|
||||
{
|
||||
Thread * const dst = Thread::pool()->object(user_arg_1());
|
||||
if (!dst) {
|
||||
@@ -470,21 +458,22 @@ void Thread::_call_request_and_wait()
|
||||
size_t msg_size;
|
||||
void * buf_base;
|
||||
size_t buf_size;
|
||||
_utcb_phys->call_request_and_wait(msg_base, msg_size,
|
||||
buf_base, buf_size);
|
||||
_utcb_phys->message()->info_about_send_request(msg_base, msg_size,
|
||||
buf_base, buf_size);
|
||||
Ipc_node::send_request_await_reply(dst, msg_base, msg_size,
|
||||
buf_base, buf_size);
|
||||
}
|
||||
|
||||
|
||||
void Thread::_call_reply()
|
||||
void Thread::_call_send_reply_msg()
|
||||
{
|
||||
void * msg_base;
|
||||
size_t msg_size;
|
||||
_utcb_phys->call_reply(msg_base, msg_size);
|
||||
_utcb_phys->message()->info_about_send_reply(msg_base, msg_size);
|
||||
Ipc_node::send_reply(msg_base, msg_size);
|
||||
bool const await_request = user_arg_1();
|
||||
if (await_request) { _call_wait_for_request(); }
|
||||
bool const await_request_msg = user_arg_1();
|
||||
if (await_request_msg) { _call_await_request_msg(); }
|
||||
else { user_arg_0(0); }
|
||||
}
|
||||
|
||||
|
||||
@@ -608,8 +597,86 @@ void Thread::_call_update_region()
|
||||
}
|
||||
|
||||
|
||||
void Thread::_print_activity_table()
|
||||
{
|
||||
for (unsigned id = 0; id < MAX_THREADS; id++) {
|
||||
Thread * const t = Thread::pool()->object(id);
|
||||
if (!t) { continue; }
|
||||
t->_print_activity(t == this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void Thread::_print_activity(bool const printing_thread)
|
||||
{
|
||||
static Thread * idle = dynamic_cast<Thread *>(cpu_scheduler()->idle());
|
||||
Genode::printf("\033[33m[%u] %s", pd_id(), pd_label());
|
||||
Genode::printf(" (%u) %s:\033[0m", id(), label());
|
||||
if (id() == idle->id()) {
|
||||
Genode::printf("\033[32m run\033[0m");
|
||||
_print_common_activity();
|
||||
return;
|
||||
}
|
||||
switch (_state) {
|
||||
case AWAITS_START: {
|
||||
Genode::printf("\033[32m init\033[0m");
|
||||
break; }
|
||||
case SCHEDULED: {
|
||||
if (!printing_thread) { Genode::printf("\033[32m run\033[0m"); }
|
||||
else { Genode::printf("\033[32m debug\033[0m"); }
|
||||
break; }
|
||||
case AWAITS_IPC: {
|
||||
_print_activity_when_awaits_ipc();
|
||||
break; }
|
||||
case AWAITS_RESUME: {
|
||||
Genode::printf("\033[32m await RES\033[0m");
|
||||
break; }
|
||||
case AWAITS_SIGNAL: {
|
||||
unsigned const receiver_id = Signal_handler::receiver()->id();
|
||||
Genode::printf("\033[32m await SIG %u\033[0m", receiver_id);
|
||||
break; }
|
||||
case AWAITS_SIGNAL_CONTEXT_KILL: {
|
||||
unsigned const context_id = Signal_context_killer::context()->id();
|
||||
Genode::printf("\033[32m await SCK %u\033[0m", context_id);
|
||||
break; }
|
||||
case STOPPED: {
|
||||
Genode::printf("\033[32m stop\033[0m");
|
||||
break; }
|
||||
}
|
||||
_print_common_activity();
|
||||
}
|
||||
|
||||
|
||||
void Thread::_print_common_activity()
|
||||
{
|
||||
Genode::printf(" ip %lx sp %lx\n", ip, sp);
|
||||
}
|
||||
|
||||
|
||||
void Thread::_print_activity_when_awaits_ipc()
|
||||
{
|
||||
switch (Ipc_node::state()) {
|
||||
case AWAIT_REPLY: {
|
||||
Thread * const server = dynamic_cast<Thread *>(Ipc_node::outbuf_dst());
|
||||
Genode::printf("\033[32m await RPL %u\033[0m", server->id());
|
||||
break; }
|
||||
case AWAIT_REQUEST: {
|
||||
Genode::printf("\033[32m await REQ\033[0m");
|
||||
break; }
|
||||
case PREPARE_AND_AWAIT_REPLY: {
|
||||
Thread * const server = dynamic_cast<Thread *>(Ipc_node::outbuf_dst());
|
||||
Genode::printf("\033[32m prep RPL await RPL %u\033[0m", server->id());
|
||||
break; }
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Thread::_call_print_char()
|
||||
{
|
||||
char const c = user_arg_1();
|
||||
if (!c) { _print_activity_table(); }
|
||||
Genode::printf("%c", (char)user_arg_1());
|
||||
}
|
||||
|
||||
@@ -648,13 +715,8 @@ void Thread::_call_new_signal_context()
|
||||
/* create and assign context*/
|
||||
void * const p = (void *)user_arg_1();
|
||||
unsigned const imprint = user_arg_3();
|
||||
try {
|
||||
Signal_context * const c = new (p) Signal_context(r, imprint);
|
||||
user_arg_0(c->id());
|
||||
} catch (Signal_context::Assign_to_receiver_failed) {
|
||||
PERR("failed to assign context to receiver");
|
||||
user_arg_0(0);
|
||||
}
|
||||
Signal_context * const c = new (p) Signal_context(r, imprint);
|
||||
user_arg_0(c->id());
|
||||
}
|
||||
|
||||
|
||||
@@ -735,6 +797,25 @@ void Thread::_call_ack_signal()
|
||||
|
||||
|
||||
void Thread::_call_kill_signal_context()
|
||||
{
|
||||
/* lookup signal context */
|
||||
unsigned const id = user_arg_1();
|
||||
Signal_context * const c = Signal_context::pool()->object(id);
|
||||
if (!c) {
|
||||
PERR("unknown signal context");
|
||||
user_arg_0(-1);
|
||||
return;
|
||||
}
|
||||
/* kill signal context */
|
||||
if (c->kill(this)) {
|
||||
PERR("failed to kill signal context");
|
||||
user_arg_0(-1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Thread::_call_bin_signal_context()
|
||||
{
|
||||
/* check permissions */
|
||||
if (!_core()) {
|
||||
@@ -750,17 +831,13 @@ void Thread::_call_kill_signal_context()
|
||||
user_arg_0(0);
|
||||
return;
|
||||
}
|
||||
/* kill signal context */
|
||||
if (c->kill(this)) {
|
||||
PERR("failed to kill signal context");
|
||||
user_arg_0(-1);
|
||||
return;
|
||||
}
|
||||
/* destruct signal context */
|
||||
c->~Signal_context();
|
||||
user_arg_0(0);
|
||||
}
|
||||
|
||||
|
||||
void Thread::_call_kill_signal_receiver()
|
||||
void Thread::_call_bin_signal_receiver()
|
||||
{
|
||||
/* check permissions */
|
||||
if (!_core()) {
|
||||
@@ -776,12 +853,7 @@ void Thread::_call_kill_signal_receiver()
|
||||
user_arg_0(0);
|
||||
return;
|
||||
}
|
||||
/* kill signal receiver */
|
||||
if (r->kill(this)) {
|
||||
PERR("unknown signal receiver");
|
||||
user_arg_0(-1);
|
||||
return;
|
||||
}
|
||||
r->~Signal_receiver();
|
||||
user_arg_0(0);
|
||||
}
|
||||
|
||||
@@ -863,14 +935,14 @@ void Thread::_call()
|
||||
{
|
||||
switch (user_arg_0()) {
|
||||
case Call_id::NEW_THREAD: _call_new_thread(); return;
|
||||
case Call_id::KILL_THREAD: _call_kill_thread(); return;
|
||||
case Call_id::BIN_THREAD: _call_bin_thread(); return;
|
||||
case Call_id::START_THREAD: _call_start_thread(); return;
|
||||
case Call_id::PAUSE_THREAD: _call_pause_thread(); return;
|
||||
case Call_id::RESUME_THREAD: _call_resume_thread(); return;
|
||||
case Call_id::YIELD_THREAD: _call_yield_thread(); return;
|
||||
case Call_id::REQUEST_AND_WAIT: _call_request_and_wait(); return;
|
||||
case Call_id::REPLY: _call_reply(); return;
|
||||
case Call_id::WAIT_FOR_REQUEST: _call_wait_for_request(); return;
|
||||
case Call_id::SEND_REQUEST_MSG: _call_send_request_msg(); return;
|
||||
case Call_id::SEND_REPLY_MSG: _call_send_reply_msg(); return;
|
||||
case Call_id::AWAIT_REQUEST_MSG: _call_await_request_msg(); return;
|
||||
case Call_id::UPDATE_PD: _call_update_pd(); return;
|
||||
case Call_id::UPDATE_REGION: _call_update_region(); return;
|
||||
case Call_id::NEW_PD: _call_new_pd(); return;
|
||||
@@ -878,7 +950,8 @@ void Thread::_call()
|
||||
case Call_id::NEW_SIGNAL_RECEIVER: _call_new_signal_receiver(); return;
|
||||
case Call_id::NEW_SIGNAL_CONTEXT: _call_new_signal_context(); return;
|
||||
case Call_id::KILL_SIGNAL_CONTEXT: _call_kill_signal_context(); return;
|
||||
case Call_id::KILL_SIGNAL_RECEIVER: _call_kill_signal_receiver(); return;
|
||||
case Call_id::BIN_SIGNAL_CONTEXT: _call_bin_signal_context(); return;
|
||||
case Call_id::BIN_SIGNAL_RECEIVER: _call_bin_signal_receiver(); return;
|
||||
case Call_id::AWAIT_SIGNAL: _call_await_signal(); return;
|
||||
case Call_id::SUBMIT_SIGNAL: _call_submit_signal(); return;
|
||||
case Call_id::SIGNAL_PENDING: _call_signal_pending(); return;
|
||||
@@ -886,7 +959,7 @@ void Thread::_call()
|
||||
case Call_id::NEW_VM: _call_new_vm(); return;
|
||||
case Call_id::RUN_VM: _call_run_vm(); return;
|
||||
case Call_id::PAUSE_VM: _call_pause_vm(); return;
|
||||
case Call_id::KILL_PD: _call_kill_pd(); return;
|
||||
case Call_id::BIN_PD: _call_bin_pd(); return;
|
||||
case Call_id::ACCESS_THREAD_REGS: _call_access_thread_regs(); return;
|
||||
case Call_id::ROUTE_THREAD_EVENT: _call_route_thread_event(); return;
|
||||
default:
|
||||
|
||||
@@ -51,7 +51,6 @@ class Kernel::Thread
|
||||
public Execution_context,
|
||||
public Ipc_node,
|
||||
public Signal_context_killer,
|
||||
public Signal_receiver_killer,
|
||||
public Signal_handler,
|
||||
public Thread_cpu_support
|
||||
{
|
||||
@@ -69,8 +68,7 @@ class Kernel::Thread
|
||||
AWAITS_RESUME = 4,
|
||||
AWAITS_SIGNAL = 5,
|
||||
AWAITS_SIGNAL_CONTEXT_KILL = 6,
|
||||
AWAITS_SIGNAL_RECEIVER_KILL = 7,
|
||||
STOPPED = 8,
|
||||
STOPPED = 7,
|
||||
};
|
||||
|
||||
State _state;
|
||||
@@ -177,22 +175,44 @@ class Kernel::Thread
|
||||
*/
|
||||
addr_t Thread::* _reg(addr_t const id) const;
|
||||
|
||||
/**
|
||||
* Print table of all threads and their current activity
|
||||
*/
|
||||
void _print_activity_table();
|
||||
|
||||
/**
|
||||
* Print the activity of the thread
|
||||
*
|
||||
* \param printing_thread wether this thread caused the debugging
|
||||
*/
|
||||
void _print_activity(bool const printing_thread);
|
||||
|
||||
/**
|
||||
* Print the activity of the thread when it awaits a message
|
||||
*/
|
||||
void _print_activity_when_awaits_ipc();
|
||||
|
||||
/**
|
||||
* Print activity info that is printed regardless of the thread state
|
||||
*/
|
||||
void _print_common_activity();
|
||||
|
||||
|
||||
/****************************************************************
|
||||
** Kernel-call backends, for details see 'kernel/interface.h' **
|
||||
****************************************************************/
|
||||
|
||||
void _call_new_pd();
|
||||
void _call_kill_pd();
|
||||
void _call_bin_pd();
|
||||
void _call_new_thread();
|
||||
void _call_kill_thread();
|
||||
void _call_bin_thread();
|
||||
void _call_start_thread();
|
||||
void _call_pause_thread();
|
||||
void _call_resume_thread();
|
||||
void _call_yield_thread();
|
||||
void _call_wait_for_request();
|
||||
void _call_request_and_wait();
|
||||
void _call_reply();
|
||||
void _call_await_request_msg();
|
||||
void _call_send_request_msg();
|
||||
void _call_send_reply_msg();
|
||||
void _call_update_pd();
|
||||
void _call_update_region();
|
||||
void _call_print_char();
|
||||
@@ -203,7 +223,8 @@ class Kernel::Thread
|
||||
void _call_submit_signal();
|
||||
void _call_ack_signal();
|
||||
void _call_kill_signal_context();
|
||||
void _call_kill_signal_receiver();
|
||||
void _call_bin_signal_context();
|
||||
void _call_bin_signal_receiver();
|
||||
void _call_new_vm();
|
||||
void _call_run_vm();
|
||||
void _call_pause_vm();
|
||||
@@ -216,17 +237,10 @@ class Kernel::Thread
|
||||
***************************/
|
||||
|
||||
void _signal_context_kill_pending();
|
||||
void _signal_context_kill_failed();
|
||||
void _signal_context_kill_done();
|
||||
|
||||
|
||||
/****************************
|
||||
** Signal_receiver_killer **
|
||||
****************************/
|
||||
|
||||
void _signal_receiver_kill_pending();
|
||||
void _signal_receiver_kill_done();
|
||||
|
||||
|
||||
/********************
|
||||
** Signal_handler **
|
||||
********************/
|
||||
|
||||
@@ -16,6 +16,6 @@
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
Vm_ids * vm_ids() { return unsynchronized_singleton<Vm_ids>(); }
|
||||
Vm_pool * vm_pool() { return unsynchronized_singleton<Vm_pool>(); }
|
||||
Vm_ids * vm_ids() { return unmanaged_singleton<Vm_ids>(); }
|
||||
Vm_pool * vm_pool() { return unmanaged_singleton<Vm_pool>(); }
|
||||
}
|
||||
|
||||
84
base-hw/src/core/odroid_xu/platform_support.cc
Normal file
84
base-hw/src/core/odroid_xu/platform_support.cc
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* \brief Parts of platform that are specific to Odroid XU
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2013-11-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <board.h>
|
||||
#include <platform.h>
|
||||
#include <pic.h>
|
||||
#include <cpu.h>
|
||||
#include <timer.h>
|
||||
#include <kernel/irq.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
namespace Kernel { void init_platform(); }
|
||||
|
||||
/**
|
||||
* Interrupts that core shall provide to users
|
||||
*/
|
||||
static unsigned irq_ids[] =
|
||||
{
|
||||
Board::PWM_IRQ_0,
|
||||
};
|
||||
|
||||
enum { IRQ_IDS_SIZE = sizeof(irq_ids)/sizeof(irq_ids[0]) };
|
||||
|
||||
|
||||
void Kernel::init_platform()
|
||||
{
|
||||
/* make user IRQs become known by cores IRQ session backend and kernel */
|
||||
static uint8_t _irqs[IRQ_IDS_SIZE][sizeof(Irq)];
|
||||
for (unsigned i = 0; i < IRQ_IDS_SIZE; i++) {
|
||||
new (_irqs[i]) Irq(irq_ids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned * Platform::_irq(unsigned const i)
|
||||
{
|
||||
return i < IRQ_IDS_SIZE ? &irq_ids[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_ram_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Board::RAM_0_BASE, Board::RAM_0_SIZE },
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Board::MMIO_0_BASE, Board::MMIO_0_SIZE },
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Board::GIC_CPU_MMIO_BASE, Board::GIC_CPU_MMIO_SIZE },
|
||||
{ Board::MCT_MMIO_BASE, Board::MCT_MMIO_SIZE },
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Cpu::User_context::User_context() { cpsr = Psr::init_user(); }
|
||||
44
base-hw/src/core/odroid_xu/target.mk
Normal file
44
base-hw/src/core/odroid_xu/target.mk
Normal file
@@ -0,0 +1,44 @@
|
||||
#
|
||||
# \brief Build config for Genodes core process
|
||||
# \author Stefan Kalkowski
|
||||
# \date 2013-11-25
|
||||
#
|
||||
|
||||
# declare wich specs must be given to build this target
|
||||
REQUIRES += platform_odroid_xu
|
||||
|
||||
# add include paths
|
||||
INC_DIR += $(REP_DIR)/src/core/odroid_xu
|
||||
INC_DIR += $(REP_DIR)/src/core/exynos5
|
||||
INC_DIR += $(REP_DIR)/src/core/arm
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += platform_services.cc \
|
||||
platform_support.cc \
|
||||
cpu_support.cc
|
||||
|
||||
# add assembly sources
|
||||
SRC_S += mode_transition.s \
|
||||
boot_modules.s \
|
||||
crt0.s
|
||||
|
||||
# declare source paths
|
||||
vpath platform_services.cc $(BASE_DIR)/src/core
|
||||
vpath platform_support.cc $(REP_DIR)/src/core/odroid_xu
|
||||
vpath mode_transition.s $(REP_DIR)/src/core/arm_v7
|
||||
vpath cpu_support.cc $(REP_DIR)/src/core/arm
|
||||
vpath crt0.s $(REP_DIR)/src/core/arm
|
||||
|
||||
#
|
||||
# Check if there are other images wich shall be linked to core.
|
||||
# If not use a dummy boot-modules file wich includes only the symbols.
|
||||
#
|
||||
ifeq ($(wildcard $(BUILD_BASE_DIR)/boot_modules.s),)
|
||||
vpath boot_modules.s $(REP_DIR)/src/core/arm
|
||||
else
|
||||
INC_DIR += $(BUILD_BASE_DIR)
|
||||
vpath boot_modules.s $(BUILD_BASE_DIR)
|
||||
endif
|
||||
|
||||
# include less specific target parts
|
||||
include $(REP_DIR)/src/core/target.inc
|
||||
@@ -109,10 +109,12 @@ Native_region * Platform::_core_only_ram_regions(unsigned const i)
|
||||
}
|
||||
|
||||
|
||||
Platform::Platform() :
|
||||
Platform::Platform()
|
||||
:
|
||||
_core_mem_alloc(0),
|
||||
_io_mem_alloc(core_mem_alloc()), _io_port_alloc(core_mem_alloc()),
|
||||
_irq_alloc(core_mem_alloc()), _vm_base(0x1000), _vm_size(0xfffef000)
|
||||
_irq_alloc(core_mem_alloc()),
|
||||
_vm_start(VIRT_ADDR_SPACE_START), _vm_size(VIRT_ADDR_SPACE_SIZE)
|
||||
{
|
||||
/*
|
||||
* Initialise platform resource allocators.
|
||||
@@ -173,7 +175,7 @@ Platform::Platform() :
|
||||
|
||||
void Core_parent::exit(int exit_value)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
Kernel::log() << __PRETTY_FUNCTION__ << "not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Platform_pd::~Platform_pd()
|
||||
{
|
||||
_tlb->remove_region(platform()->vm_start(), platform()->vm_size());
|
||||
regain_ram_from_tlb(_tlb);
|
||||
if (Kernel::kill_pd(_id)) {
|
||||
if (Kernel::bin_pd(_id)) {
|
||||
PERR("failed to destruct protection domain at kernel");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ using namespace Genode;
|
||||
|
||||
namespace Kernel { unsigned core_id(); }
|
||||
|
||||
void Platform_thread::_init() { }
|
||||
|
||||
|
||||
bool Platform_thread::_attaches_utcb_by_itself()
|
||||
{
|
||||
@@ -69,7 +71,7 @@ Platform_thread::~Platform_thread()
|
||||
rm->remove_client(cap);
|
||||
}
|
||||
/* destroy object at the kernel */
|
||||
Kernel::kill_thread(_id);
|
||||
Kernel::bin_thread(_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -158,23 +160,12 @@ int Platform_thread::join_pd(unsigned const pd_id, bool const main_thread,
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::_init()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::start(void * const ip, void * const sp,
|
||||
unsigned int const cpu_id)
|
||||
{
|
||||
/* attach UTCB if the thread can't do this by itself */
|
||||
if (!_attaches_utcb_by_itself())
|
||||
{
|
||||
/* declare page aligned virtual UTCB outside the context area */
|
||||
_utcb_virt = (Native_utcb *)((platform()->vm_start()
|
||||
+ platform()->vm_size() - sizeof(Native_utcb))
|
||||
& ~((1<<MIN_MAPPING_SIZE_LOG2)-1));
|
||||
|
||||
/* attach UTCB */
|
||||
/* attach UTCB in case of a main thread */
|
||||
if (_main_thread) {
|
||||
_utcb_virt = main_thread_utcb();
|
||||
if (!_rm_client) {
|
||||
PERR("invalid RM client");
|
||||
return -1;
|
||||
@@ -186,22 +177,19 @@ int Platform_thread::start(void * const ip, void * const sp,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* initialize thread regisers */
|
||||
/* initialize thread registers */
|
||||
typedef Kernel::Thread_reg_id Reg_id;
|
||||
enum { WRITES = 2 };
|
||||
addr_t * write_regs = (addr_t *)Thread_base::myself()->utcb()->base();
|
||||
write_regs[0] = Reg_id::IP;
|
||||
write_regs[1] = Reg_id::SP;
|
||||
addr_t write_values[] = {
|
||||
(addr_t)ip,
|
||||
_main_thread ? (addr_t)_utcb_virt : (addr_t)sp
|
||||
};
|
||||
addr_t write_values[] = { (addr_t)ip, (addr_t)sp };
|
||||
if (Kernel::access_thread_regs(id(), 0, WRITES, 0, write_values)) {
|
||||
PERR("failed to initialize thread registers");
|
||||
return -1;
|
||||
}
|
||||
/* start executing new thread */
|
||||
_utcb_phys->startup_msg.init(_id);
|
||||
_utcb_phys->start_info()->init(_id, _utcb);
|
||||
_tlb = Kernel::start_thread(_id, cpu_id, _pd_id, _utcb_phys);
|
||||
if (!_tlb) {
|
||||
PERR("failed to start thread");
|
||||
|
||||
@@ -137,7 +137,7 @@ void Signal_session_component::free_context(Signal_context_capability cap)
|
||||
void Signal_session_component::_destruct_context(Context * const c)
|
||||
{
|
||||
/* release kernel resources */
|
||||
if (Kernel::kill_signal_context(c->id()))
|
||||
if (Kernel::bin_signal_context(c->id()))
|
||||
{
|
||||
/* clean-up */
|
||||
c->release();
|
||||
@@ -153,7 +153,7 @@ void Signal_session_component::_destruct_context(Context * const c)
|
||||
void Signal_session_component::_destruct_receiver(Receiver * const r)
|
||||
{
|
||||
/* release kernel resources */
|
||||
if (Kernel::kill_signal_receiver(r->id()))
|
||||
if (Kernel::bin_signal_receiver(r->id()))
|
||||
{
|
||||
/* clean-up */
|
||||
r->release();
|
||||
|
||||
@@ -22,7 +22,8 @@ INC_DIR += $(REP_DIR)/src/core \
|
||||
$(BASE_DIR)/src/core/include \
|
||||
$(BASE_DIR)/include \
|
||||
$(BASE_DIR)/src/platform \
|
||||
$(BASE_DIR)/src/base/thread
|
||||
$(BASE_DIR)/src/base/thread \
|
||||
$(BASE_DIR)/src/base/include
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += console.cc \
|
||||
|
||||
@@ -31,7 +31,6 @@ Native_utcb * Thread_base::utcb()
|
||||
{
|
||||
if (this) { return _tid.platform_thread->utcb_virt(); }
|
||||
return _main_thread_utcb;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -54,9 +53,7 @@ void Thread_base::_thread_start()
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Thread_base(const char * const label, size_t const stack_size)
|
||||
:
|
||||
_list_element(this)
|
||||
Thread_base::Thread_base(const char * const label, size_t const stack_size, Type)
|
||||
{
|
||||
_tid.platform_thread = new (platform()->core_mem_alloc())
|
||||
Platform_thread(stack_size, Kernel::core_id(), label);
|
||||
@@ -65,7 +62,7 @@ Thread_base::Thread_base(const char * const label, size_t const stack_size)
|
||||
|
||||
Thread_base::~Thread_base()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
Kernel::log() << __PRETTY_FUNCTION__ << "not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* \brief Platform-specific helper functions for the _main() function
|
||||
* \author Martin Stein
|
||||
* \author Christian Helmuth
|
||||
* \date 2010-09-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/native_types.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
namespace Genode { void platform_main_bootstrap(); }
|
||||
|
||||
Native_thread_id _main_thread_id;
|
||||
|
||||
|
||||
Native_thread_id Genode::thread_get_my_native_id()
|
||||
{
|
||||
Thread_base * const t = Thread_base::myself();
|
||||
return t ? t->tid().thread_id : _main_thread_id;
|
||||
}
|
||||
|
||||
|
||||
void Genode::platform_main_bootstrap()
|
||||
{
|
||||
/* go save against multiple calls e.g. for programs with dynamic linker */
|
||||
static bool main_thread_id_valid = 0;
|
||||
if (!main_thread_id_valid) {
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
_main_thread_id = utcb->startup_msg.thread_id();
|
||||
main_thread_id_valid = 1;
|
||||
}
|
||||
}
|
||||
@@ -131,13 +131,15 @@ namespace Genode {
|
||||
* Please update platform-specific files after changing these
|
||||
* values, e.g., 'base-linux/src/platform/context_area.*.ld'.
|
||||
*/
|
||||
static addr_t context_area_virtual_base() { return 0x40000000UL; }
|
||||
static addr_t context_area_virtual_size() { return 0x10000000UL; }
|
||||
static constexpr addr_t context_area_virtual_base() {
|
||||
return 0x40000000UL; }
|
||||
static constexpr addr_t context_area_virtual_size() {
|
||||
return 0x10000000UL; }
|
||||
|
||||
/**
|
||||
* Size of virtual address region holding the context of one thread
|
||||
*/
|
||||
static addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
};
|
||||
|
||||
class Native_pd_args
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user