L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
examples/sys/start-with-exc/main.c

This example shows how to start a newly created thread with a defined set of CPU registers.

This example shows how to start a newly created thread with a defined set of CPU registers.

/*
* (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
* Alexander Warg <warg@os.inf.tu-dresden.de>,
* Björn Döbel <doebel@os.inf.tu-dresden.de>,
* Frank Mehnert <fm3@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
*
* This file is part of TUD:OS and distributed under the terms of the
* GNU General Public License 2.
* Please see the COPYING-GPL-2 file for details.
*/
/*
* Start a thread with an exception reply. This example does only work on
* the x86-32 and ARM architectures.
*/
#include <l4/sys/thread.h>
#include <l4/sys/factory.h>
#include <l4/sys/ipc.h>
#include <l4/sys/utcb.h>
#include <l4/util/util.h>
#include <l4/re/env.h>
#include <stdlib.h>
#include <stdio.h>
/* Stack for the thread to be created. 8kB are enough. */
static char thread_stack[8 << 10];
/* The thread to be created. For illustration it will print out its
* register set.
*/
static void L4_STICKY(thread_func(l4_umword_t *d))
{
while (1)
{
printf("hey, I'm a thread\n");
printf("got register values: %ld %ld %ld %ld %ld %ld %ld\n",
d[7], d[6], d[5], d[4], d[2], d[1], d[0]);
l4_sleep(800);
}
}
/* Startup trick for this example. Put all the CPU registers on the stack so
* that the C function above can get it on the stack. */
asm(
".global thread \n"
"thread: \n"
#ifdef ARCH_x86
" pusha \n"
" push %esp \n"
" call thread_func \n"
#endif
#ifdef ARCH_arm
" push {r0-r7} \n"
" mov r0, sp \n"
" bl thread_func \n"
#endif
#ifdef ARCH_arm64
" stp x0, x1, [sp, #0]! \n"
" stp x2, x3, [sp, #0]! \n"
" stp x4, x5, [sp, #0]! \n"
" stp x6, x7, [sp, #0]! \n"
" mov x0, sp \n"
" bl thread_func \n"
#endif
);
extern void thread(void);
/* Our main function */
int main(void)
{
/* Get a capability slot for our new thread. */
l4_exc_regs_t *e = l4_utcb_exc_u(u);
int err;
printf("Example showing how to start a thread with an exception.\n");
/* We do not want to implement a pager here, take the shortcut. */
printf("Make sure to start this program with ldr-flags=eager_map\n");
return 1;
/* Create the thread using our default factory */
tag = l4_factory_create_thread(l4re_env()->factory, t1);
if (l4_error(tag))
return 1;
/* Setup the thread by setting the pager and task. */
l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb,
L4RE_THIS_TASK_CAP);
if (l4_error(tag))
return 2;
/* Start the thread by finally setting instruction and stack pointer */
(l4_umword_t)thread,
(l4_umword_t)thread_stack + sizeof(thread_stack),
if (l4_error(tag))
return 3;
tag = l4_scheduler_run_thread(l4re_env()->scheduler, t1, &sp);
if (l4_error(tag))
return 4;
/* Receive initial exception from just started thread */
if ((err = l4_ipc_error(tag, u)))
{
printf("Umm, ipc error: %x\n", err);
return 1;
}
/* We expect an exception IPC */
{
printf("PF?: %lx %lx (not prepared to handle this) %ld\n",
l4_utcb_mr_u(u)->mr[0], l4_utcb_mr_u(u)->mr[1], l4_msgtag_label(tag));
return 1;
}
/* Fill out the complete register set of the new thread */
e->sp = (l4_umword_t)(thread_stack + sizeof(thread_stack));
#ifdef ARCH_x86
e->ip = (l4_umword_t)thread;
e->edi = 0;
e->esi = 1;
e->ebp = 2;
e->ebx = 4;
e->edx = 5;
e->ecx = 6;
e->eax = 7;
#endif
#ifdef ARCH_arm
e->pc = (l4_umword_t)thread;
e->r[0] = 0;
e->r[1] = 1;
e->r[2] = 2;
e->r[3] = 3;
e->r[4] = 4;
e->r[5] = 5;
e->r[6] = 6;
e->r[7] = 7;
#endif
#ifdef ARCH_arm64
e->pc = (l4_umword_t)thread;
e->r[0] = 0;
e->r[1] = 1;
e->r[2] = 2;
e->r[3] = 3;
e->r[4] = 4;
e->r[5] = 5;
e->r[6] = 6;
e->r[7] = 7;
#endif
/* Send a complete exception */
tag = l4_msgtag(0, L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0);
/* Send reply and start the thread with the defined CPU register set */
tag = l4_ipc_send(t1, u, tag, L4_IPC_NEVER);
if ((err = l4_ipc_error(tag, u)))
printf("Error sending IPC: %x\n", err);
/* Idle around */
while (1)
l4_sleep(10000);
return 0;
}
Capability allocator C interface.
Environment interface.
Common factory related definitions.
l4_cap_idx_t l4re_util_cap_alloc(void) L4_NOTHROW
Get free capability index at capability allocator.
l4re_env_t * l4re_env(void) L4_NOTHROW
Get L4Re initial environment.
Definition env.h:190
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:51
unsigned long l4_cap_idx_t
Capability selector type.
Definition types.h:359
unsigned l4_is_invalid_cap(l4_cap_idx_t c) L4_NOTHROW
Test if a capability selector is the invalid capability.
Definition types.h:412
l4_msgtag_t l4_factory_create_thread(l4_cap_idx_t factory, l4_cap_idx_t target_cap) L4_NOTHROW
Create a new thread.
Definition factory.h:488
l4_msgtag_t l4_ipc_receive(l4_cap_idx_t object, l4_utcb_t *utcb, l4_timeout_t timeout) L4_NOTHROW
Wait for a message from a specific source.
Definition ipc.h:613
l4_msgtag_t l4_ipc_send(l4_cap_idx_t dest, l4_utcb_t *utcb, l4_msgtag_t tag, l4_timeout_t timeout) L4_NOTHROW
Send a message to an object (do not wait for a reply).
Definition ipc.h:597
long l4_error(l4_msgtag_t tag) L4_NOTHROW
Get IPC error code if any or message tag label otherwise for an IPC call.
Definition ipc.h:657
l4_umword_t l4_ipc_error(l4_msgtag_t tag, l4_utcb_t *utcb) L4_NOTHROW
Get the IPC error code for an IPC operation.
Definition ipc.h:640
unsigned l4_msgtag_is_exception(l4_msgtag_t t) L4_NOTHROW
Test for exception protocol.
Definition types.h:471
l4_msgtag_t l4_msgtag(long label, unsigned words, unsigned items, unsigned flags) L4_NOTHROW
Create a message tag from the specified values.
Definition types.h:428
long l4_msgtag_label(l4_msgtag_t t) L4_NOTHROW
Get the protocol of tag.
Definition types.h:440
l4_msgtag_t l4_scheduler_run_thread(l4_cap_idx_t scheduler, l4_cap_idx_t thread, l4_sched_param_t const *sp) L4_NOTHROW)
Run a thread on a Scheduler.
Definition scheduler.h:398
l4_sched_param_t l4_sched_param(unsigned prio, l4_umword_t quantum=0) L4_NOTHROW
Construct scheduler parameter.
Definition scheduler.h:291
l4_msgtag_t l4_thread_ex_regs(l4_cap_idx_t thread, l4_addr_t ip, l4_addr_t sp, l4_umword_t flags) L4_NOTHROW
Exchange basic thread registers.
Definition thread.h:912
@ L4_THREAD_EX_REGS_TRIGGER_EXCEPTION
Trigger artificial exception in thread.
Definition thread.h:762
void l4_thread_control_bind(l4_utcb_t *thread_utcb, l4_cap_idx_t task) L4_NOTHROW
Bind the thread to a task.
Definition thread.h:945
l4_msgtag_t l4_thread_control_commit(l4_cap_idx_t thread) L4_NOTHROW
Commit the thread control parameters.
Definition thread.h:963
void l4_thread_control_exc_handler(l4_cap_idx_t exc_handler) L4_NOTHROW
Set the exception handler.
Definition thread.h:938
void l4_thread_control_start(void) L4_NOTHROW
Start a thread control API sequence.
Definition thread.h:926
void l4_thread_control_pager(l4_cap_idx_t pager) L4_NOTHROW
Set the pager.
Definition thread.h:932
#define L4_IPC_NEVER
never timeout
Definition __timeout.h:84
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition utcb.h:67
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
Definition utcb.h:340
#define L4_STICKY(x)
Mark symbol sticky (even not there)
Definition compiler.h:300
void l4_sleep(l4_uint32_t ms) L4_NOTHROW
Suspend thread for a period of ms milliseconds.
UTCB structure for exceptions.
Definition utcb.h:39
l4_umword_t sp
stack pointer
Definition utcb.h:44
l4_umword_t ip
instruction pointer
Definition utcb.h:78
l4_umword_t r[13]
registers
Definition utcb.h:43
l4_umword_t edx
edx register
Definition utcb.h:84
l4_umword_t pc
pc
Definition utcb.h:47
l4_umword_t esi
esi register
Definition utcb.h:80
l4_umword_t ebp
ebp register
Definition utcb.h:81
l4_umword_t eax
eax register
Definition utcb.h:86
l4_umword_t ecx
ecx register
Definition utcb.h:85
l4_umword_t ebx
ebx register
Definition utcb.h:83
l4_umword_t edi
edi register
Definition utcb.h:79
Message tag data structure.
Definition types.h:164
Scheduler parameter set.
Definition scheduler.h:185