]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/examples/sys/aliens/main.c
30216f9b80cb0c787206499584a924fdf43a6e16
[l4.git] / l4 / pkg / examples / sys / aliens / main.c
1 /*
2  * (c) 2008-2009 Technische Universität Dresden
3  * This file is part of TUD:OS and distributed under the terms of the
4  * GNU General Public License 2.
5  * Please see the COPYING-GPL-2 file for details.
6  */
7 /*
8  * Example to show syscall tracing.
9  */
10 //#define MEASURE
11
12 #include <l4/sys/ipc.h>
13 #include <l4/sys/thread.h>
14 #include <l4/sys/factory.h>
15 #include <l4/sys/utcb.h>
16 #include <l4/sys/kdebug.h>
17 #include <l4/util/util.h>
18 #include <l4/util/rdtsc.h>
19 #include <l4/re/env.h>
20 #include <l4/re/c/util/cap_alloc.h>
21 #include <l4/sys/debugger.h>
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26
27
28 static char alien_thread_stack[8 << 10];
29 static l4_cap_idx_t alien;
30
31 static void alien_thread(void)
32 {
33   volatile l4_msgtag_t x;
34   while (1) {
35     x = l4_ipc_call(0x1234 << L4_CAP_SHIFT, l4_utcb(), l4_msgtag(0, 0, 0, 0), L4_IPC_NEVER);
36 #ifdef MEASURE
37     l4_sleep(0);
38 #else
39     l4_sleep(1000);
40     outstring("An int3 -- you should see this\n");
41     outnstring("345", 3);
42 #endif
43   }
44
45 }
46
47 int main(void)
48 {
49   l4_msgtag_t tag;
50 #ifdef MEASURE
51   l4_cpu_time_t s, e;
52 #endif
53   l4_utcb_t *u = l4_utcb();
54   l4_exc_regs_t exc;
55   l4_umword_t mr0, mr1;
56
57   printf("Alien feature testing\n");
58
59   l4_debugger_set_object_name(l4re_env()->main_thread, "alientest");
60
61   /* Start alien thread */
62   if (l4_is_invalid_cap(alien = l4re_util_cap_alloc()))
63     return 1;
64
65   l4_touch_rw(alien_thread_stack, sizeof(alien_thread_stack));
66
67   tag = l4_factory_create_thread(l4re_env()->factory, alien);
68   if (l4_msgtag_has_error(tag))
69     return 1;
70
71   l4_debugger_set_object_name(alien, "alienth");
72
73   l4_thread_control_start();
74   l4_thread_control_pager(l4re_env()->main_thread);
75   l4_thread_control_exc_handler(l4re_env()->main_thread);
76   l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb, L4RE_THIS_TASK_CAP);
77   l4_thread_control_alien(1);
78   tag = l4_thread_control_commit(alien);
79   if (l4_msgtag_has_error(tag))
80     return 2;
81
82   tag = l4_thread_ex_regs(alien,
83                           (l4_umword_t)alien_thread,
84                           (l4_umword_t)alien_thread_stack + sizeof(alien_thread_stack),
85                           0);
86   if (l4_msgtag_has_error(tag))
87     return 3;
88
89 #ifdef MEASURE
90   l4_calibrate_tsc(l4re_kip());
91 #endif
92
93   /* Pager/Exception loop */
94   if (l4_msgtag_has_error(tag = l4_ipc_receive(alien, u, L4_IPC_NEVER)))
95     {
96       printf("l4_ipc_receive failed");
97       return 1;
98     }
99
100   memcpy(&exc, l4_utcb_exc(), sizeof(exc));
101   mr0 = l4_utcb_mr()->mr[0];
102   mr1 = l4_utcb_mr()->mr[1];
103
104   for (;;)
105     {
106 #ifdef MEASURE
107       s = l4_rdtsc();
108 #endif
109
110       if (l4_msgtag_is_exception(tag))
111         {
112 #ifndef MEASURE
113           printf("PC=%08lx SP=%08lx Err=%08lx Trap=%lx, %s syscall, SC-Nr: %lx\n",
114                  l4_utcb_exc_pc(&exc), exc.sp, exc.err,
115                  exc.trapno, (exc.err & 4) ? " after" : "before",
116                  exc.err >> 3);
117 #endif
118           tag = l4_msgtag((exc.err & 4) ? 0 : L4_PROTO_ALLOW_SYSCALL,
119                           L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0);
120         }
121       else
122         printf("Umm, non-handled request (like PF): %lx %lx\n", mr0, mr1);
123
124       memcpy(l4_utcb_exc(), &exc, sizeof(exc));
125
126       /* Reply and wait */
127       if (l4_msgtag_has_error(tag = l4_ipc_call(alien, u, tag, L4_IPC_NEVER)))
128         {
129           printf("l4_ipc_call failed\n");
130           return 1;
131         }
132       memcpy(&exc, l4_utcb_exc(), sizeof(exc));
133       mr0 = l4_utcb_mr()->mr[0];
134       mr1 = l4_utcb_mr()->mr[1];
135 #ifdef MEASURE
136       e = l4_rdtsc();
137       printf("time %lld\n", l4_tsc_to_ns(e - s));
138 #endif
139     }
140
141   return 0;
142 }