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