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.
8 * Single stepping example for the x86-32 architecture.
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>
16 #include <l4/util/util.h>
17 #include <l4/re/env.h>
18 #include <l4/re/c/util/cap_alloc.h>
24 static char thread_stack[8 << 10];
26 static void thread_func(void)
32 /* Enable single stepping */
33 asm volatile("pushf; pop %0; or $256,%0; push %0; popf\n"
34 : "=r" (d) : "r" (d));
36 /* Some instructions */
40 asm volatile("mov $12345678, %%edx" : : : "edx"); // a non-existant cap
41 asm volatile("int $0x30\n");
46 /* Disabled single stepping */
47 asm volatile("pushf; pop %0; and $~256,%0; push %0; popf\n"
48 : "=r" (d) : "r" (d));
50 /* You won't see those */
61 l4_cap_idx_t th = l4re_util_cap_alloc();
64 l4_utcb_t *u = l4_utcb();
66 printf("Singlestep testing\n");
68 if (l4_is_invalid_cap(th))
71 l4_touch_rw(thread_stack, sizeof(thread_stack));
72 l4_touch_ro(thread_func, 1);
74 tag = l4_factory_create_thread(l4re_env()->factory, th);
75 if (l4_msgtag_has_error(tag))
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,
83 l4_thread_control_alien(1);
84 tag = l4_thread_control_commit(th);
85 if (l4_msgtag_has_error(tag))
88 tag = l4_thread_ex_regs(th, (l4_umword_t)thread_func,
89 (l4_umword_t)thread_stack + sizeof(thread_stack),
91 if (l4_msgtag_has_error(tag))
94 /* Pager/Exception loop */
95 if (l4_msgtag_has_error(tag = l4_ipc_receive(th, u, L4_IPC_NEVER)))
97 printf("l4_ipc_receive failed");
100 memcpy(&exc, l4_utcb_exc(), sizeof(exc));
101 mr0 = l4_utcb_mr()->mr[0];
102 mr1 = l4_utcb_mr()->mr[1];
106 if (l4_msgtag_is_exception(tag))
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);
115 tag = l4_msgtag(L4_PROTO_ALLOW_SYSCALL,
116 L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0);
118 enter_kdebug("Should not be 1");
122 tag = l4_msgtag(L4_PROTO_NONE,
123 L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0);
125 enter_kdebug("Should not be 0");
127 ipc_stat = !ipc_stat;
132 printf("Umm, non-handled request: %ld, %08lx %08lx\n",
133 l4_msgtag_label(tag), mr0, mr1);
135 memcpy(l4_utcb_exc(), &exc, sizeof(exc));
138 if (l4_msgtag_has_error(tag = l4_ipc_call(th, u, tag, L4_IPC_NEVER)))
140 printf("l4_ipc_call failed\n");
143 memcpy(&exc, l4_utcb_exc(), sizeof(exc));
144 mr0 = l4_utcb_mr()->mr[0];
145 mr1 = l4_utcb_mr()->mr[1];