source: mainline/kernel/generic/src/udebug/udebug_ipc.c@ 9a1b20c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9a1b20c was 9a1b20c, checked in by Jiri Svoboda <jirik.svoboda@…>, 17 years ago

Merge syscall tracer (trace) and relevant part of udebug interface from tracing to trunk.

  • Property mode set to 100644
File size: 6.9 KB
Line 
1/*
2 * Copyright (c) 2008 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup generic
30 * @{
31 */
32
33/**
34 * @file
35 * @brief Udebug IPC message handling.
36 */
37
38#include <print.h>
39#include <proc/task.h>
40#include <proc/thread.h>
41#include <arch.h>
42#include <errno.h>
43#include <ipc/ipc.h>
44#include <syscall/copy.h>
45#include <udebug/udebug.h>
46#include <udebug/udebug_ops.h>
47#include <udebug/udebug_ipc.h>
48
49int udebug_request_preprocess(call_t *call, phone_t *phone)
50{
51 switch (IPC_GET_ARG1(call->data)) {
52 /* future UDEBUG_M_REGS_WRITE, UDEBUG_M_MEM_WRITE: */
53 default:
54 break;
55 }
56
57 return 0;
58}
59
60static void udebug_receive_begin(call_t *call)
61{
62 int rc;
63
64 rc = udebug_begin(call);
65 if (rc < 0) {
66 IPC_SET_RETVAL(call->data, rc);
67 ipc_answer(&TASK->kernel_box, call);
68 return;
69 }
70
71 if (rc != 0) {
72 IPC_SET_RETVAL(call->data, 0);
73 ipc_answer(&TASK->kernel_box, call);
74 }
75}
76
77static void udebug_receive_end(call_t *call)
78{
79 int rc;
80
81 rc = udebug_end();
82
83 IPC_SET_RETVAL(call->data, rc);
84 ipc_answer(&TASK->kernel_box, call);
85}
86
87static void udebug_receive_set_evmask(call_t *call)
88{
89 int rc;
90 udebug_evmask_t mask;
91
92 mask = IPC_GET_ARG2(call->data);
93 rc = udebug_set_evmask(mask);
94
95 IPC_SET_RETVAL(call->data, rc);
96 ipc_answer(&TASK->kernel_box, call);
97}
98
99
100static void udebug_receive_go(call_t *call)
101{
102 thread_t *t;
103 int rc;
104
105 //printf("debug_go()\n");
106
107 t = (thread_t *)IPC_GET_ARG2(call->data);
108
109 rc = udebug_go(t, call);
110 if (rc < 0) {
111 IPC_SET_RETVAL(call->data, rc);
112 ipc_answer(&TASK->kernel_box, call);
113 return;
114 }
115}
116
117static void udebug_receive_stop(call_t *call)
118{
119 thread_t *t;
120 int rc;
121
122 printf("debug_stop()\n");
123
124 t = (thread_t *)IPC_GET_ARG2(call->data);
125
126 rc = udebug_stop(t, call);
127 IPC_SET_RETVAL(call->data, rc);
128 ipc_answer(&TASK->kernel_box, call);
129}
130
131static void udebug_receive_thread_read(call_t *call)
132{
133 unative_t uspace_addr;
134 unative_t to_copy;
135 unsigned total_bytes;
136 unsigned buf_size;
137 void *buffer;
138 size_t n;
139 int rc;
140
141 uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */
142 buf_size = IPC_GET_ARG3(call->data); /* Dest. buffer size */
143
144 /*
145 * Read thread list. Variable n will be filled with actual number
146 * of threads times thread-id size.
147 */
148 rc = udebug_thread_read(&buffer, buf_size, &n);
149 if (rc < 0) {
150 IPC_SET_RETVAL(call->data, rc);
151 ipc_answer(&TASK->kernel_box, call);
152 return;
153 }
154
155 total_bytes = n;
156
157 /* Copy MAX(buf_size, total_bytes) bytes */
158
159 if (buf_size > total_bytes)
160 to_copy = total_bytes;
161 else
162 to_copy = buf_size;
163
164 /*
165 * Make use of call->buffer to transfer data to caller's userspace
166 */
167
168 IPC_SET_RETVAL(call->data, 0);
169 /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
170 same code in process_answer() can be used
171 (no way to distinguish method in answer) */
172 IPC_SET_ARG1(call->data, uspace_addr);
173 IPC_SET_ARG2(call->data, to_copy);
174
175 IPC_SET_ARG3(call->data, total_bytes);
176 call->buffer = buffer;
177
178 ipc_answer(&TASK->kernel_box, call);
179}
180
181static void udebug_receive_args_read(call_t *call)
182{
183 thread_t *t;
184 unative_t uspace_addr;
185 int rc;
186 void *buffer;
187
188 t = (thread_t *)IPC_GET_ARG2(call->data);
189
190 rc = udebug_args_read(t, &buffer);
191 if (rc != EOK) {
192 IPC_SET_RETVAL(call->data, rc);
193 ipc_answer(&TASK->kernel_box, call);
194 return;
195 }
196
197 /*
198 * Make use of call->buffer to transfer data to caller's userspace
199 */
200
201 uspace_addr = IPC_GET_ARG3(call->data);
202
203 IPC_SET_RETVAL(call->data, 0);
204 /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
205 same code in process_answer() can be used
206 (no way to distinguish method in answer) */
207 IPC_SET_ARG1(call->data, uspace_addr);
208 IPC_SET_ARG2(call->data, 6 * sizeof(unative_t));
209 call->buffer = buffer;
210
211 ipc_answer(&TASK->kernel_box, call);
212}
213
214static void udebug_receive_mem_read(call_t *call)
215{
216 unative_t uspace_dst;
217 unative_t uspace_src;
218 unsigned size;
219 void *buffer;
220 int rc;
221
222 uspace_dst = IPC_GET_ARG2(call->data);
223 uspace_src = IPC_GET_ARG3(call->data);
224 size = IPC_GET_ARG4(call->data);
225
226 rc = udebug_mem_read(uspace_src, size, &buffer);
227 if (rc < 0) {
228 IPC_SET_RETVAL(call->data, rc);
229 ipc_answer(&TASK->kernel_box, call);
230 return;
231 }
232
233 IPC_SET_RETVAL(call->data, 0);
234 /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
235 same code in process_answer() can be used
236 (no way to distinguish method in answer) */
237 IPC_SET_ARG1(call->data, uspace_dst);
238 IPC_SET_ARG2(call->data, size);
239 call->buffer = buffer;
240
241 ipc_answer(&TASK->kernel_box, call);
242}
243
244/**
245 * Handle a debug call received on the kernel answerbox.
246 *
247 * This is called by the kbox servicing thread.
248 */
249void udebug_call_receive(call_t *call)
250{
251 int debug_method;
252
253 debug_method = IPC_GET_ARG1(call->data);
254
255 if (debug_method != UDEBUG_M_BEGIN) {
256 /*
257 * Verify that the sender is this task's debugger.
258 * Note that this is the only thread that could change
259 * TASK->debugger. Therefore no locking is necessary
260 * and the sender can be safely considered valid until
261 * control exits this function.
262 */
263 if (TASK->udebug.debugger != call->sender) {
264 IPC_SET_RETVAL(call->data, EINVAL);
265 ipc_answer(&TASK->kernel_box, call);
266 return;
267 }
268 }
269
270 switch (debug_method) {
271 case UDEBUG_M_BEGIN:
272 udebug_receive_begin(call);
273 break;
274 case UDEBUG_M_END:
275 udebug_receive_end(call);
276 break;
277 case UDEBUG_M_SET_EVMASK:
278 udebug_receive_set_evmask(call);
279 break;
280 case UDEBUG_M_GO:
281 udebug_receive_go(call);
282 break;
283 case UDEBUG_M_STOP:
284 udebug_receive_stop(call);
285 break;
286 case UDEBUG_M_THREAD_READ:
287 udebug_receive_thread_read(call);
288 break;
289 case UDEBUG_M_ARGS_READ:
290 udebug_receive_args_read(call);
291 break;
292 case UDEBUG_M_MEM_READ:
293 udebug_receive_mem_read(call);
294 break;
295 }
296}
297
298/** @}
299 */
Note: See TracBrowser for help on using the repository browser.