Loading...
Searching...
No Matches
examples/sys/utcb-ipc/main.c

This example shows how to send IPC using the UTCB to store payload.

This example shows how to send IPC using the UTCB to store payload.

/*
* (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>
* 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.
*/
#include <l4/sys/ipc.h>
#include <l4/sys/thread.h>
#include <l4/sys/factory.h>
#include <l4/sys/utcb.h>
#include <l4/sys/task.h>
#include <l4/sys/vcon.h>
#include <l4/re/env.h>
#include <l4/re/c/util/cap_alloc.h>
#include <l4/re/c/util/kumem_alloc.h>
#include <l4/util/thread.h>
#include <stdio.h>
#include <string.h>
static unsigned char stack2[8 << 10] __attribute__((aligned(8)));
static l4_cap_idx_t thread1_cap, thread2_cap;
static void vlogprintn(const char *s, int l)
{
if (l > L4_VCON_WRITE_SIZE)
l = L4_VCON_WRITE_SIZE;
l4_vcon_send(L4_BASE_LOG_CAP, s, l);
}
static void vlogprint(const char *s)
{
vlogprintn(s, strlen(s));
}
static void vlogprintc(const char c)
{
vlogprintn(&c, 1);
}
static void thread1(void)
{
l4_msg_regs_t *mr = l4_utcb_mr();
l4_msgtag_t tag;
int i, j;
printf("Thread1 up (%p)\n", l4_utcb());
for (i = 0; i < 10; i++)
{
for (j = 0; j < L4_UTCB_GENERIC_DATA_SIZE; j++)
mr->mr[j] = 'A' + (i + j) % ('~' - 'A' + 1);
tag = l4_msgtag(0, L4_UTCB_GENERIC_DATA_SIZE, 0, 0);
if (l4_msgtag_has_error(l4_ipc_send(thread2_cap, l4_utcb(), tag, L4_IPC_NEVER)))
printf("IPC-send error\n");
}
mr->mr[0] = 1;
if (l4_msgtag_has_error(l4_ipc_send(thread2_cap, l4_utcb(), tag, L4_IPC_NEVER)))
printf("IPC-send error\n");
printf("Thread1 done\n");
}
L4UTIL_THREAD_STATIC_FUNC(thread2)
{
l4_msgtag_t tag;
l4_msg_regs_t mr;
unsigned i;
// No printf() here because this would require a working pthread environment!
vlogprint("Thread2 up\n");
while (1)
{
if (l4_msgtag_has_error(tag = l4_ipc_receive(thread1_cap, l4_utcb(), L4_IPC_NEVER)))
vlogprint("IPC receive error\n");
memcpy(&mr, l4_utcb_mr(), sizeof(mr));
if (mr.mr[0] == 1) // exit notification
break;
vlogprint("Thread2 receive: ");
for (i = 0; i < l4_msgtag_words(tag); i++)
vlogprintc((char)mr.mr[i]);
vlogprint("\n");
}
vlogprint("Thread2 done, switching to thread1\n");
if (l4_msgtag_has_error(l4_ipc_send(thread1_cap, l4_utcb(),
tag, L4_IPC_NEVER)))
vlogprint("IPC-send error\n");
// In theory this could hit if the above IPC send operation doesn't switch
// to the other thread.
__builtin_trap();
}
int main(void)
{
l4_msgtag_t tag;
thread1_cap = l4re_env()->main_thread;
thread2_cap = l4re_util_cap_alloc();
if (l4_is_invalid_cap(thread2_cap))
{
printf("Cannot allocate thread2 capability\n");
return 1;
}
tag = l4_factory_create_thread(l4re_env()->factory, thread2_cap);
if (l4_error(tag))
{
printf("Cannot create thread2\n");
return 2;
}
l4_addr_t kumem;
if (l4re_util_kumem_alloc(&kumem, 0, L4RE_THIS_TASK_CAP, l4re_env()->rm))
{
printf("Cannot allocate UTCB for thread2\n");
return 3;
}
l4_thread_control_start();
l4_thread_control_pager(l4re_env()->rm);
l4_thread_control_exc_handler(l4re_env()->rm);
l4_thread_control_bind((l4_utcb_t *)kumem, L4RE_THIS_TASK_CAP);
tag = l4_thread_control_commit(thread2_cap);
if (l4_error(tag))
{
printf("Cannot set thread2 thread parameters\n");
return 4;
}
tag = l4_thread_ex_regs(thread2_cap,
(l4_umword_t)thread2,
(l4_umword_t)(stack2 + sizeof(stack2)), 0);
if (l4_error(tag))
{
printf("Cannot set thread2 IP/SP\n");
return 5;
}
l4_sched_param_t sp = l4_sched_param(1, 0);
tag = l4_scheduler_run_thread(l4re_env()->scheduler, thread2_cap, &sp);
if (l4_error(tag))
{
printf("Cannot start thread2\n");
return 6;
}
thread1();
if (l4_msgtag_has_error(l4_ipc_receive(thread2_cap, l4_utcb(),
L4_IPC_NEVER)))
printf("IPC-receive error\n");
l4_task_unmap(L4RE_THIS_TASK_CAP,
l4_obj_fpage(thread2_cap, 0, L4_FPAGE_RWX),
L4_FP_ALL_SPACES);
printf("Terminated thread2. Terminating.\n");
return 0;
}
cap_alloc.h
Capability allocator C interface.
env.h
Environment interface.
factory.h
Common factory related definitions.
l4re_util_cap_alloc
L4_BEGIN_DECLS l4_cap_idx_t l4re_util_cap_alloc(void) L4_NOTHROW
Get free capability index at capability allocator.
l4re_env
l4re_env_t * l4re_env(void) L4_NOTHROW
Get L4Re initial environment.
Definition env.h:181
l4_umword_t
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
l4_addr_t
unsigned long l4_addr_t
Address type.
Definition l4int.h:34
l4_cap_idx_t
unsigned long l4_cap_idx_t
Capability selector type.
Definition types.h:336
l4_is_invalid_cap
unsigned l4_is_invalid_cap(l4_cap_idx_t c) L4_NOTHROW
Test if a capability selector is the invalid capability.
Definition types.h:389
L4_BASE_LOG_CAP
@ L4_BASE_LOG_CAP
Capability selector for the log object.
Definition consts.h:347
l4_factory_create_thread
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:538
l4_obj_fpage
l4_fpage_t l4_obj_fpage(l4_cap_idx_t obj, unsigned int order, unsigned char rights) L4_NOTHROW
Create a kernel-object flexpage.
Definition __l4_fpage.h:715
L4_FPAGE_RWX
@ L4_FPAGE_RWX
Read-write-execute flexpage.
Definition __l4_fpage.h:125
l4_ipc_receive
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:602
l4_ipc_send
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:586
l4_error
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:646
l4_msgtag_has_error
unsigned l4_msgtag_has_error(l4_msgtag_t t) L4_NOTHROW
Test for error indicator flag.
Definition types.h:440
l4_msgtag
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:405
l4_msgtag_words
unsigned l4_msgtag_words(l4_msgtag_t t) L4_NOTHROW
Get the number of untyped words.
Definition types.h:427
l4_scheduler_run_thread
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:396
l4_sched_param
l4_sched_param_t l4_sched_param(unsigned prio, l4_umword_t quantum=0) L4_NOTHROW
Construct scheduler parameter.
Definition scheduler.h:289
l4_task_unmap
l4_msgtag_t l4_task_unmap(l4_cap_idx_t task, l4_fpage_t fpage, l4_umword_t map_mask) L4_NOTHROW
Revoke rights from the task.
Definition task.h:440
L4_FP_ALL_SPACES
@ L4_FP_ALL_SPACES
Flag to tell the unmap operation to revoke permissions from all child mappings including the mapping ...
Definition consts.h:183
l4_thread_ex_regs
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:942
l4_thread_control_bind
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:975
l4_thread_control_commit
l4_msgtag_t l4_thread_control_commit(l4_cap_idx_t thread) L4_NOTHROW
Commit the thread control parameters.
Definition thread.h:987
l4_thread_control_exc_handler
void l4_thread_control_exc_handler(l4_cap_idx_t exc_handler) L4_NOTHROW
Set the exception handler.
Definition thread.h:968
l4_thread_control_start
void l4_thread_control_start(void) L4_NOTHROW
Start a thread control API sequence.
Definition thread.h:956
l4_thread_control_pager
void l4_thread_control_pager(l4_cap_idx_t pager) L4_NOTHROW
Set the pager.
Definition thread.h:962
L4_IPC_NEVER
#define L4_IPC_NEVER
never timeout
Definition __timeout.h:76
l4_utcb_mr
l4_msg_regs_t * l4_utcb_mr(void) L4_NOTHROW L4_PURE
Get the message-register block of a UTCB.
Definition utcb.h:358
l4_utcb_t
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition utcb.h:56
l4_utcb
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
Definition utcb.h:346
l4_vcon_send
l4_msgtag_t l4_vcon_send(l4_cap_idx_t vcon, char const *buf, unsigned size) L4_NOTHROW
Send data to virtual console.
Definition vcon.h:315
L4_VCON_WRITE_SIZE
@ L4_VCON_WRITE_SIZE
Maximum size that can be written with one l4_vcon_write call.
Definition vcon.h:98
kumem_alloc.h
Kumem allocator utility C interface.
l4re_util_kumem_alloc
L4_BEGIN_DECLS int l4re_util_kumem_alloc(l4_addr_t *mem, unsigned pages_order, l4_cap_idx_t task, l4_cap_idx_t rm) L4_NOTHROW
Allocate state area.
thread.h
Low-level Thread Functions.
string.h
String.
l4_msgtag_t
Message tag data structure.
Definition types.h:154
l4_sched_param_t
Scheduler parameter set.
Definition scheduler.h:174
l4re_env_t::main_thread
l4_cap_idx_t main_thread
Object-capability of the first user thread.
Definition env.h:104
l4_msg_regs_t
Encapsulation of the message-register block in the UTCB.
Definition utcb.h:68
l4_msg_regs_t::mr
l4_umword_t mr[L4_UTCB_GENERIC_DATA_SIZE]
Message registers.
Definition utcb.h:69
vcon.h
Virtual console interface.