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)
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.
12 * Single stepping example for the x86-32 architecture.
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>
20 #include <l4/util/util.h>
21 #include <l4/re/env.h>
22 #include <l4/re/c/util/cap_alloc.h>
28 static char thread_stack[8 << 10];
30 static void thread_func(void)
36 /* Enable single stepping */
37 asm volatile("pushf; pop %0; or $256,%0; push %0; popf\n"
38 : "=r" (d) : "r" (d));
40 /* Some instructions */
44 asm volatile("mov $0x12345000, %%edx" : : : "edx"); // a non-existent cap
45 asm volatile("int $0x30\n");
50 /* Disabled single stepping */
51 asm volatile("pushf; pop %0; and $~256,%0; push %0; popf\n"
52 : "=r" (d) : "r" (d));
54 /* You won't see those */
65 l4_cap_idx_t th = l4re_util_cap_alloc();
68 l4_utcb_t *u = l4_utcb();
70 printf("Singlestep testing\n");
72 if (l4_is_invalid_cap(th))
75 l4_touch_rw(thread_stack, sizeof(thread_stack));
76 l4_touch_ro(thread_func, 1);
78 tag = l4_factory_create_thread(l4re_env()->factory, th);
79 if (l4_msgtag_has_error(tag))
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,
87 l4_thread_control_alien(1);
88 tag = l4_thread_control_commit(th);
89 if (l4_msgtag_has_error(tag))
92 tag = l4_thread_ex_regs(th, (l4_umword_t)thread_func,
93 (l4_umword_t)thread_stack + sizeof(thread_stack),
95 if (l4_msgtag_has_error(tag))
98 /* Pager/Exception loop */
99 if (l4_msgtag_has_error(tag = l4_ipc_receive(th, u, L4_IPC_NEVER)))
101 printf("l4_ipc_receive failed");
104 memcpy(&exc, l4_utcb_exc(), sizeof(exc));
105 mr0 = l4_utcb_mr()->mr[0];
106 mr1 = l4_utcb_mr()->mr[1];
110 if (l4_msgtag_is_exception(tag))
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);
119 tag = l4_msgtag(L4_PROTO_ALLOW_SYSCALL,
120 L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0);
122 enter_kdebug("Should not be 1");
126 tag = l4_msgtag(L4_PROTO_NONE,
127 L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0);
129 enter_kdebug("Should not be 0");
131 ipc_stat = !ipc_stat;
136 printf("Umm, non-handled request: %ld, %08lx %08lx\n",
137 l4_msgtag_label(tag), mr0, mr1);
139 memcpy(l4_utcb_exc(), &exc, sizeof(exc));
142 if (l4_msgtag_has_error(tag = l4_ipc_call(th, u, tag, L4_IPC_NEVER)))
144 printf("l4_ipc_call failed\n");
147 memcpy(&exc, l4_utcb_exc(), sizeof(exc));
148 mr0 = l4_utcb_mr()->mr[0];
149 mr1 = l4_utcb_mr()->mr[1];