1 /*
2 * (c) 2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
3 * economic rights: Technische Universität Dresden (Germany)
4 *
5 * This file is part of TUD:OS and distributed under the terms of the
6 * GNU General Public License 2.
7 * Please see the COPYING-GPL-2 file for details.
8 *
9 * As a special exception, you may use this file as part of a free software
10 * library without restriction. Specifically, if other files instantiate
11 * templates or use macros or inline functions from this file, or you compile
12 * this file and link it with other files to produce an executable, this
13 * file does not by itself cause the resulting executable to be covered by
14 * the GNU General Public License. This exception does not however
15 * invalidate any other reasons why the executable file might be covered by
16 * the GNU General Public License.
17 */
18
19 #pragma once
20
21 #ifndef __KDEBUG_H__
22 #define __KDEBUG_H__
23
24 #include <l4/sys/compiler.h>
25 #include <l4/sys/consts.h>
26 #include <l4/sys/ipc.h>
27
28
29 L4_INLINE void
30 enter_kdebug(char const *text) L4_NOTHROW;
31
32 enum l4_kdebug_ops_t
33 {
34 L4_KDEBUG_ENTER = 0,
35 L4_KDEBUG_OUTCHAR = 1,
36 L4_KDEBUG_OUTNSTRING = 2,
37 L4_KDEBUG_OUTHEX32 = 3,
38 L4_KDEBUG_OUTHEX20 = 4,
39 L4_KDEBUG_OUTHEX16 = 5,
40 L4_KDEBUG_OUTHEX12 = 6,
41 L4_KDEBUG_OUTHEX8 = 7,
42 L4_KDEBUG_OUTDEC = 8,
43 };
44
45
46 L4_INLINE l4_msgtag_t
__kdebug_op(unsigned op)47 __kdebug_op(unsigned op) L4_NOTHROW
48 {
49 l4_msgtag_t res;
50 l4_utcb_t *u = l4_utcb();
51 l4_msg_regs_t *mr = l4_utcb_mr_u(u);
52 l4_umword_t mr0 = mr->mr[0];
53
54 mr->mr[0] = op;
55 res = l4_ipc_call(L4_BASE_DEBUGGER_CAP, u,
56 l4_msgtag(L4_PROTO_DEBUGGER, 1, 0, 0),
57 L4_IPC_NEVER);
58 mr->mr[0] = mr0;
59 return res;
60 }
61
62 L4_INLINE l4_msgtag_t
__kdebug_text(unsigned op,char const * text,unsigned len)63 __kdebug_text(unsigned op, char const *text, unsigned len) L4_NOTHROW
64 {
65 l4_msg_regs_t store;
66 l4_msgtag_t res;
67 l4_utcb_t *u = l4_utcb();
68 l4_msg_regs_t *mr = l4_utcb_mr_u(u);
69
70 if (len > (sizeof(store) - (2 * sizeof(l4_umword_t))))
71 len = sizeof(store) - (2 * sizeof(l4_umword_t));
72
73 __builtin_memcpy(&store, mr, sizeof(store));
74 mr->mr[0] = op;
75 mr->mr[1] = len;
76 __builtin_memcpy(&mr->mr[2], text, len);
77 res = l4_ipc_call(L4_BASE_DEBUGGER_CAP, u,
78 l4_msgtag(L4_PROTO_DEBUGGER,
79 l4_bytes_to_mwords(len) + 2, 0, 0),
80 L4_IPC_NEVER);
81 __builtin_memcpy(mr, &store, sizeof(*mr));
82 return res;
83 }
84
85 L4_INLINE l4_msgtag_t
__kdebug_3_text(unsigned op,char const * text,unsigned len,l4_umword_t v1,l4_umword_t v2,l4_umword_t v3)86 __kdebug_3_text(unsigned op, char const *text, unsigned len,
87 l4_umword_t v1, l4_umword_t v2, l4_umword_t v3) L4_NOTHROW
88 {
89 l4_msg_regs_t store;
90 l4_msgtag_t res;
91 l4_utcb_t *u = l4_utcb();
92 l4_msg_regs_t *mr = l4_utcb_mr_u(u);
93
94 if (len > (sizeof(store) - (5 * sizeof(l4_umword_t))))
95 len = sizeof(store) - (5 * sizeof(l4_umword_t));
96
97 __builtin_memcpy(&store, mr, sizeof(store));
98 mr->mr[0] = op;
99 mr->mr[1] = v1;
100 mr->mr[2] = v2;
101 mr->mr[3] = v3;
102 mr->mr[4] = len;
103 __builtin_memcpy(&mr->mr[5], text, len);
104 res = l4_ipc_call(L4_BASE_DEBUGGER_CAP, u,
105 l4_msgtag(L4_PROTO_DEBUGGER,
106 l4_bytes_to_mwords(len) + 5, 0, 0),
107 L4_IPC_NEVER);
108 __builtin_memcpy(mr, &store, sizeof(*mr));
109 return res;
110 }
111
112 L4_INLINE l4_msgtag_t
__kdebug_op_1(unsigned op,l4_mword_t val)113 __kdebug_op_1(unsigned op, l4_mword_t val) L4_NOTHROW
114 {
115 l4_umword_t m[2];
116 l4_msgtag_t res;
117 l4_utcb_t *u = l4_utcb();
118 l4_msg_regs_t *mr = l4_utcb_mr_u(u);
119
120 m[0] = mr->mr[0];
121 m[1] = mr->mr[1];
122 mr->mr[0] = op;
123 mr->mr[1] = val;
124 res = l4_ipc_call(L4_BASE_DEBUGGER_CAP, u,
125 l4_msgtag(L4_PROTO_DEBUGGER, 2, 0, 0),
126 L4_IPC_NEVER);
127 mr->mr[0] = m[0];
128 mr->mr[1] = m[1];
129 return res;
130 }
131
enter_kdebug(char const * text)132 L4_INLINE void enter_kdebug(char const *text) L4_NOTHROW
133 {
134 /* special case, enter without any text and use of the UTCB */
135 if (!text)
136 {
137 l4_ipc_call(L4_BASE_DEBUGGER_CAP, 0,
138 l4_msgtag(L4_PROTO_DEBUGGER, 0, 0, 0),
139 L4_IPC_NEVER);
140 return;
141 }
142
143 __kdebug_text(L4_KDEBUG_ENTER, text, __builtin_strlen(text));
144 }
145
outnstring(char const * text,unsigned len)146 L4_INLINE void outnstring(char const *text, unsigned len)
147 { __kdebug_text(L4_KDEBUG_OUTNSTRING, text, len); }
148
outstring(char const * text)149 L4_INLINE void outstring(char const *text)
150 { outnstring(text, __builtin_strlen(text)); }
151
152
outchar(char c)153 L4_INLINE void outchar(char c)
154 {
155 __kdebug_op_1(L4_KDEBUG_OUTCHAR, c);
156 }
157
outumword(l4_umword_t number)158 L4_INLINE void outumword(l4_umword_t number)
159 {
160 if (sizeof(l4_umword_t) == sizeof(l4_uint64_t))
161 __kdebug_op_1(L4_KDEBUG_OUTHEX32, (l4_uint64_t)number >> 32);
162
163 __kdebug_op_1(L4_KDEBUG_OUTHEX32, number);
164 }
165
outhex64(l4_uint64_t number)166 L4_INLINE void outhex64(l4_uint64_t number)
167 {
168 __kdebug_op_1(L4_KDEBUG_OUTHEX32, number >> 32);
169 __kdebug_op_1(L4_KDEBUG_OUTHEX32, number);
170 }
171
outhex32(l4_uint32_t number)172 L4_INLINE void outhex32(l4_uint32_t number)
173 {
174 __kdebug_op_1(L4_KDEBUG_OUTHEX32, number);
175 }
176
outhex20(l4_uint32_t number)177 L4_INLINE void outhex20(l4_uint32_t number)
178 {
179 __kdebug_op_1(L4_KDEBUG_OUTHEX20, number);
180 }
181
outhex16(l4_uint16_t number)182 L4_INLINE void outhex16(l4_uint16_t number)
183 {
184 __kdebug_op_1(L4_KDEBUG_OUTHEX16, number);
185 }
186
outhex12(l4_uint16_t number)187 L4_INLINE void outhex12(l4_uint16_t number)
188 {
189 __kdebug_op_1(L4_KDEBUG_OUTHEX12, number);
190 }
191
outhex8(l4_uint8_t number)192 L4_INLINE void outhex8(l4_uint8_t number)
193 {
194 __kdebug_op_1(L4_KDEBUG_OUTHEX8, number);
195 }
196
outdec(l4_mword_t number)197 L4_INLINE void outdec(l4_mword_t number)
198 {
199 __kdebug_op_1(L4_KDEBUG_OUTDEC, number);
200 }
201
202 #endif //__KDEBUG_H__
203