]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/examples/sys/singlestep/main.c
be8c8ab9de9e4b5895c5cda45a03be2507df3e84
[l4.git] / l4 / pkg / examples / sys / singlestep / main.c
1 /*
2  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3  *               Alexander Warg <warg@os.inf.tu-dresden.de>,
4  *               Björn Döbel <doebel@os.inf.tu-dresden.de>
5  *     economic rights: Technische Universität Dresden (Germany)
6  *
7  * This file is part of TUD:OS and distributed under the terms of the
8  * GNU General Public License 2.
9  * Please see the COPYING-GPL-2 file for details.
10  */
11 /*
12  * Single stepping example for the x86-32 architecture.
13  */
14 #include <l4/sys/ipc.h>
15 #include <l4/sys/factory.h>
16 #include <l4/sys/thread.h>
17 #include <l4/sys/utcb.h>
18 #include <l4/sys/kdebug.h>
19
20 #include <l4/util/util.h>
21 #include <l4/re/env.h>
22 #include <l4/re/c/util/cap_alloc.h>
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27
28 static char thread_stack[8 << 10];
29
30 static void thread_func(void)
31 {
32   while (1)
33     {
34       unsigned long d = 0;
35
36       /* Enable single stepping  */
37       asm volatile("pushf; pop %0; or $256,%0; push %0; popf\n"
38                    : "=r" (d) : "r" (d));
39
40       /* Some instructions */
41       asm volatile("nop");
42       asm volatile("nop");
43       asm volatile("nop");
44       asm volatile("mov $0x12345000, %%edx" : : : "edx"); // a non-existent cap
45       asm volatile("int $0x30\n");
46       asm volatile("nop");
47       asm volatile("nop");
48       asm volatile("nop");
49
50       /* Disabled single stepping */
51       asm volatile("pushf; pop %0; and $~256,%0; push %0; popf\n"
52                    : "=r" (d) : "r" (d));
53
54       /* You won't see those */
55       asm volatile("nop");
56       asm volatile("nop");
57       asm volatile("nop");
58     }
59 }
60
61 int main(void)
62 {
63   l4_msgtag_t tag;
64   int ipc_stat = 0;
65   l4_cap_idx_t th = l4re_util_cap_alloc();
66   l4_exc_regs_t exc;
67   l4_umword_t mr0, mr1;
68   l4_utcb_t *u = l4_utcb();
69
70   printf("Singlestep testing\n");
71
72   if (l4_is_invalid_cap(th))
73     return 1;
74
75   l4_touch_rw(thread_stack, sizeof(thread_stack));
76   l4_touch_ro(thread_func, 1);
77
78   tag = l4_factory_create_thread(l4re_env()->factory, th);
79   if (l4_msgtag_has_error(tag))
80     return 1;
81
82   l4_thread_control_start();
83   l4_thread_control_pager(l4re_env()->main_thread);
84   l4_thread_control_exc_handler(l4re_env()->main_thread);
85   l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb,
86                           L4RE_THIS_TASK_CAP);
87   l4_thread_control_alien(1);
88   tag = l4_thread_control_commit(th);
89   if (l4_msgtag_has_error(tag))
90     return 2;
91
92   tag = l4_thread_ex_regs(th, (l4_umword_t)thread_func,
93                           (l4_umword_t)thread_stack + sizeof(thread_stack),
94                           0);
95   if (l4_msgtag_has_error(tag))
96     return 3;
97
98   /* Pager/Exception loop */
99   if (l4_msgtag_has_error(tag = l4_ipc_receive(th, u, L4_IPC_NEVER)))
100     {
101       printf("l4_ipc_receive failed");
102       return 4;
103     }
104   memcpy(&exc, l4_utcb_exc(), sizeof(exc));
105   mr0 = l4_utcb_mr()->mr[0];
106   mr1 = l4_utcb_mr()->mr[1];
107
108   for (;;)
109     {
110       if (l4_msgtag_is_exception(tag))
111         {
112           printf("PC = %08lx Trap = %08lx Err = %08lx, SP = %08lx SC-Nr: %lx\n",
113                  l4_utcb_exc_pc(&exc), exc.trapno, exc.err,
114                  exc.sp, exc.err >> 3);
115           if (exc.err >> 3)
116             {
117               if (!(exc.err & 4))
118                 {
119                   tag = l4_msgtag(L4_PROTO_ALLOW_SYSCALL,
120                                   L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0);
121                   if (ipc_stat)
122                     enter_kdebug("Should not be 1");
123                 }
124               else
125                 {
126                   tag = l4_msgtag(L4_PROTO_NONE,
127                                   L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0);
128                   if (!ipc_stat)
129                     enter_kdebug("Should not be 0");
130                 }
131               ipc_stat = !ipc_stat;
132             }
133           l4_sleep(100);
134         }
135       else
136         printf("Umm, non-handled request: %ld, %08lx %08lx\n",
137                l4_msgtag_label(tag), mr0, mr1);
138
139       memcpy(l4_utcb_exc(), &exc, sizeof(exc));
140
141       /* Reply and wait */
142       if (l4_msgtag_has_error(tag = l4_ipc_call(th, u, tag, L4_IPC_NEVER)))
143         {
144           printf("l4_ipc_call failed\n");
145           return 5;
146         }
147       memcpy(&exc, l4_utcb_exc(), sizeof(exc));
148       mr0 = l4_utcb_mr()->mr[0];
149       mr1 = l4_utcb_mr()->mr[1];
150     }
151
152   return 0;
153 }