Subversion Repositories HelenOS

Rev

Rev 2892 | Rev 2896 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2892 Rev 2894
-
 
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
 
1
/** @addtogroup generic
29
/** @addtogroup generic
2
 * @{
30
 * @{
3
 */
31
 */
4
 
32
 
5
/**
33
/**
6
 * @file
34
 * @file
7
 * @brief   Tdebug.
35
 * @brief   Udebug IPC message handling.
8
 */
36
 */
9
 
37
 
10
#include <console/klog.h>
38
#include <console/klog.h>
11
#include <proc/task.h>
39
#include <proc/task.h>
12
#include <proc/thread.h>
40
#include <proc/thread.h>
13
#include <arch.h>
41
#include <arch.h>
14
#include <errno.h>
42
#include <errno.h>
15
#include <ipc/ipc.h>
43
#include <ipc/ipc.h>
16
#include <syscall/copy.h>
44
#include <syscall/copy.h>
17
#include <udebug/udebug.h>
45
#include <udebug/udebug.h>
18
#include <udebug/udebug_ops.h>
46
#include <udebug/udebug_ops.h>
19
#include <udebug/udebug_ipc.h>
47
#include <udebug/udebug_ipc.h>
20
 
48
 
21
static int udebug_rp_regs_write(call_t *call, phone_t *phone)
49
static int udebug_rp_regs_write(call_t *call, phone_t *phone)
22
{
50
{
23
    void *uspace_data;
51
    void *uspace_data;
24
    unative_t to_copy;
52
    unative_t to_copy;
25
    int rc;
53
    int rc;
26
    void *buffer;
54
    void *buffer;
27
 
55
 
28
    klog_printf("debug_regs_write()");
56
    klog_printf("debug_regs_write()");
29
 
57
 
30
    uspace_data = (void *)IPC_GET_ARG3(call->data);
58
    uspace_data = (void *)IPC_GET_ARG3(call->data);
31
    to_copy = IPC_GET_ARG4(call->data);
59
    to_copy = IPC_GET_ARG4(call->data);
32
    if (to_copy > sizeof(istate_t)) to_copy = sizeof(istate_t);
60
    if (to_copy > sizeof(istate_t)) to_copy = sizeof(istate_t);
33
 
61
 
34
    buffer = malloc(to_copy, 0); // ??? 
62
    buffer = malloc(to_copy, 0); // ??? 
35
 
63
 
36
    rc = copy_from_uspace(buffer, uspace_data, to_copy);
64
    rc = copy_from_uspace(buffer, uspace_data, to_copy);
37
    if (rc != 0) {
65
    if (rc != 0) {
38
        klog_printf("debug_regs_write() - copy failed");
66
        klog_printf("debug_regs_write() - copy failed");
39
        return rc;
67
        return rc;
40
    }
68
    }
41
 
69
 
42
    call->buffer = buffer;
70
    call->buffer = buffer;
43
 
71
 
44
    klog_printf(" - done");
72
    klog_printf(" - done");
45
    return 0;
73
    return 0;
46
}
74
}
47
 
75
 
48
static int udebug_rp_mem_write(call_t *call, phone_t *phone)
76
static int udebug_rp_mem_write(call_t *call, phone_t *phone)
49
{
77
{
50
    void *uspace_data;
78
    void *uspace_data;
51
    unative_t to_copy;
79
    unative_t to_copy;
52
    int rc;
80
    int rc;
53
    void *buffer;
81
    void *buffer;
54
 
82
 
55
    klog_printf("udebug_rp_mem_write()");
83
    klog_printf("udebug_rp_mem_write()");
56
 
84
 
57
    uspace_data = (void *)IPC_GET_ARG2(call->data);
85
    uspace_data = (void *)IPC_GET_ARG2(call->data);
58
    to_copy = IPC_GET_ARG4(call->data);
86
    to_copy = IPC_GET_ARG4(call->data);
59
 
87
 
60
    buffer = malloc(to_copy, 0); // ???
88
    buffer = malloc(to_copy, 0); // ???
61
 
89
 
62
    rc = copy_from_uspace(buffer, uspace_data, to_copy);
90
    rc = copy_from_uspace(buffer, uspace_data, to_copy);
63
    if (rc != 0) {
91
    if (rc != 0) {
64
        klog_printf(" - copy failed");
92
        klog_printf(" - copy failed");
65
        return rc;
93
        return rc;
66
    }
94
    }
67
 
95
 
68
    call->buffer = buffer;
96
    call->buffer = buffer;
69
 
97
 
70
    klog_printf(" - done");
98
    klog_printf(" - done");
71
    return 0;
99
    return 0;
72
}
100
}
73
 
101
 
74
 
102
 
75
int udebug_request_preprocess(call_t *call, phone_t *phone)
103
int udebug_request_preprocess(call_t *call, phone_t *phone)
76
{
104
{
77
    int rc;
105
    int rc;
78
 
106
 
79
    switch (IPC_GET_ARG1(call->data)) {
107
    switch (IPC_GET_ARG1(call->data)) {
80
    case UDEBUG_M_REGS_WRITE:
108
    case UDEBUG_M_REGS_WRITE:
81
        rc = udebug_rp_regs_write(call, phone);
109
        rc = udebug_rp_regs_write(call, phone);
82
        return rc;
110
        return rc;
83
    case UDEBUG_M_MEM_WRITE:
111
    case UDEBUG_M_MEM_WRITE:
84
        rc = udebug_rp_mem_write(call, phone);
112
        rc = udebug_rp_mem_write(call, phone);
85
        return rc;
113
        return rc;
86
    default:
114
    default:
87
        break;
115
        break;
88
    }
116
    }
89
 
117
 
90
    return 0;
118
    return 0;
91
}
119
}
92
 
120
 
93
static void udebug_receive_begin(call_t *call)
121
static void udebug_receive_begin(call_t *call)
94
{
122
{
95
    int rc;
123
    int rc;
96
 
124
 
97
    rc = udebug_begin(call);
125
    rc = udebug_begin(call);
98
    if (rc < 0) {
126
    if (rc < 0) {
99
        IPC_SET_RETVAL(call->data, rc);
127
        IPC_SET_RETVAL(call->data, rc);
100
        ipc_answer(&TASK->kernel_box, call);
128
        ipc_answer(&TASK->kernel_box, call);
101
        return;
129
        return;
102
    }
130
    }
103
 
131
 
104
    if (rc != 0) {
132
    if (rc != 0) {
105
        IPC_SET_RETVAL(call->data, 0);
133
        IPC_SET_RETVAL(call->data, 0);
106
        ipc_answer(&TASK->kernel_box, call);
134
        ipc_answer(&TASK->kernel_box, call);
107
    }
135
    }
108
}
136
}
109
 
137
 
110
static void udebug_receive_end(call_t *call)
138
static void udebug_receive_end(call_t *call)
111
{
139
{
112
    int rc;
140
    int rc;
113
 
141
 
114
    rc = udebug_end();
142
    rc = udebug_end();
115
 
143
 
116
    IPC_SET_RETVAL(call->data, rc);
144
    IPC_SET_RETVAL(call->data, rc);
117
    ipc_answer(&TASK->kernel_box, call);
145
    ipc_answer(&TASK->kernel_box, call);
118
}
146
}
119
 
147
 
120
static void udebug_receive_go(call_t *call)
148
static void udebug_receive_go(call_t *call)
121
{
149
{
122
    thread_t *t;
150
    thread_t *t;
123
    int rc;
151
    int rc;
124
 
152
 
125
    klog_printf("debug_go()");
153
    klog_printf("debug_go()");
126
 
154
 
127
    t = (thread_t *)IPC_GET_ARG2(call->data);
155
    t = (thread_t *)IPC_GET_ARG2(call->data);
128
 
156
 
129
    rc = udebug_go(t, call);
157
    rc = udebug_go(t, call);
130
    if (rc < 0) {
158
    if (rc < 0) {
131
        IPC_SET_RETVAL(call->data, rc);
159
        IPC_SET_RETVAL(call->data, rc);
132
        ipc_answer(&TASK->kernel_box, call);
160
        ipc_answer(&TASK->kernel_box, call);
133
        return;
161
        return;
134
    }
162
    }
135
}
163
}
136
 
164
 
137
 
165
 
138
static void udebug_receive_thread_read(call_t *call)
166
static void udebug_receive_thread_read(call_t *call)
139
{
167
{
140
    unative_t uspace_addr;
168
    unative_t uspace_addr;
141
    unative_t to_copy;
169
    unative_t to_copy;
142
    unsigned total_bytes;
170
    unsigned total_bytes;
143
    unsigned buf_size;
171
    unsigned buf_size;
144
    void *buffer;
172
    void *buffer;
145
    size_t n;
173
    size_t n;
146
    int rc;
174
    int rc;
147
 
175
 
148
    rc = udebug_thread_read(&buffer, &n);
176
    rc = udebug_thread_read(&buffer, &n);
149
    if (rc < 0) {
177
    if (rc < 0) {
150
        IPC_SET_RETVAL(call->data, rc);
178
        IPC_SET_RETVAL(call->data, rc);
151
        ipc_answer(&TASK->kernel_box, call);
179
        ipc_answer(&TASK->kernel_box, call);
152
        return;
180
        return;
153
    }
181
    }
154
 
182
 
155
    /*
183
    /*
156
     * Make use of call->buffer to transfer data to caller's userspace
184
     * Make use of call->buffer to transfer data to caller's userspace
157
     */
185
     */
158
 
186
 
159
    uspace_addr = IPC_GET_ARG2(call->data);
187
    uspace_addr = IPC_GET_ARG2(call->data);
160
    buf_size = IPC_GET_ARG3(call->data);
188
    buf_size = IPC_GET_ARG3(call->data);
161
 
189
 
162
    total_bytes = n;
190
    total_bytes = n;
163
 
191
 
164
    if (buf_size > total_bytes)
192
    if (buf_size > total_bytes)
165
        to_copy = total_bytes;
193
        to_copy = total_bytes;
166
    else
194
    else
167
        to_copy = buf_size;
195
        to_copy = buf_size;
168
 
196
 
169
    IPC_SET_RETVAL(call->data, 0);
197
    IPC_SET_RETVAL(call->data, 0);
170
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
198
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
171
       same code in process_answer() can be used
199
       same code in process_answer() can be used
172
       (no way to distinguish method in answer) */
200
       (no way to distinguish method in answer) */
173
    IPC_SET_ARG1(call->data, uspace_addr);
201
    IPC_SET_ARG1(call->data, uspace_addr);
174
    IPC_SET_ARG2(call->data, to_copy);
202
    IPC_SET_ARG2(call->data, to_copy);
175
 
203
 
176
    IPC_SET_ARG3(call->data, total_bytes);
204
    IPC_SET_ARG3(call->data, total_bytes);
177
    call->buffer = buffer;
205
    call->buffer = buffer;
178
 
206
 
179
    ipc_answer(&TASK->kernel_box, call);
207
    ipc_answer(&TASK->kernel_box, call);
180
}
208
}
181
 
209
 
182
static void udebug_receive_args_read(call_t *call)
210
static void udebug_receive_args_read(call_t *call)
183
{
211
{
184
    thread_t *t;
212
    thread_t *t;
185
    unative_t uspace_addr;
213
    unative_t uspace_addr;
186
    int rc;
214
    int rc;
187
    void *buffer;
215
    void *buffer;
188
 
216
 
189
    t = (thread_t *)IPC_GET_ARG2(call->data);
217
    t = (thread_t *)IPC_GET_ARG2(call->data);
190
 
218
 
191
    rc = udebug_args_read(t, &buffer);
219
    rc = udebug_args_read(t, &buffer);
192
    if (rc != EOK) {
220
    if (rc != EOK) {
193
        IPC_SET_RETVAL(call->data, rc);
221
        IPC_SET_RETVAL(call->data, rc);
194
        ipc_answer(&TASK->kernel_box, call);
222
        ipc_answer(&TASK->kernel_box, call);
195
        return;
223
        return;
196
    }
224
    }
197
 
225
 
198
    /*
226
    /*
199
     * Make use of call->buffer to transfer data to caller's userspace
227
     * Make use of call->buffer to transfer data to caller's userspace
200
     */
228
     */
201
 
229
 
202
    uspace_addr = IPC_GET_ARG3(call->data);
230
    uspace_addr = IPC_GET_ARG3(call->data);
203
 
231
 
204
    IPC_SET_RETVAL(call->data, 0);
232
    IPC_SET_RETVAL(call->data, 0);
205
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
233
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
206
       same code in process_answer() can be used
234
       same code in process_answer() can be used
207
       (no way to distinguish method in answer) */
235
       (no way to distinguish method in answer) */
208
    IPC_SET_ARG1(call->data, uspace_addr);
236
    IPC_SET_ARG1(call->data, uspace_addr);
209
    IPC_SET_ARG2(call->data, 6 * sizeof(unative_t));
237
    IPC_SET_ARG2(call->data, 6 * sizeof(unative_t));
210
    call->buffer = buffer;
238
    call->buffer = buffer;
211
 
239
 
212
    ipc_answer(&TASK->kernel_box, call);
240
    ipc_answer(&TASK->kernel_box, call);
213
}
241
}
214
 
242
 
215
static void udebug_receive_regs_read(call_t *call)
243
static void udebug_receive_regs_read(call_t *call)
216
{
244
{
217
    thread_t *t;
245
    thread_t *t;
218
    unative_t uspace_addr;
246
    unative_t uspace_addr;
219
    unative_t to_copy;
247
    unative_t to_copy;
220
    unative_t buf_size;
248
    unative_t buf_size;
221
    unative_t total_bytes;
249
    unative_t total_bytes;
222
    void *buffer;
250
    void *buffer;
223
    int rc;
251
    int rc;
224
    size_t n;
252
    size_t n;
225
 
253
 
226
    klog_printf("debug_regs_read()");
254
    klog_printf("debug_regs_read()");
227
 
255
 
228
    t = (thread_t *) IPC_GET_ARG2(call->data);
256
    t = (thread_t *) IPC_GET_ARG2(call->data);
229
 
257
 
230
    rc = udebug_regs_read(t, &buffer, &n);
258
    rc = udebug_regs_read(t, &buffer, &n);
231
    if (rc < 0) {
259
    if (rc < 0) {
232
        IPC_SET_RETVAL(call->data, rc);
260
        IPC_SET_RETVAL(call->data, rc);
233
        ipc_answer(&TASK->kernel_box, call);
261
        ipc_answer(&TASK->kernel_box, call);
234
        return;
262
        return;
235
    }
263
    }
236
 
264
 
237
    /*
265
    /*
238
     * Make use of call->buffer to transfer data to caller's userspace
266
     * Make use of call->buffer to transfer data to caller's userspace
239
     */
267
     */
240
 
268
 
241
    uspace_addr = IPC_GET_ARG3(call->data);
269
    uspace_addr = IPC_GET_ARG3(call->data);
242
    buf_size = IPC_GET_ARG4(call->data);
270
    buf_size = IPC_GET_ARG4(call->data);
243
 
271
 
244
    total_bytes = n;
272
    total_bytes = n;
245
 
273
 
246
    if (buf_size > total_bytes)
274
    if (buf_size > total_bytes)
247
        to_copy = total_bytes;
275
        to_copy = total_bytes;
248
    else
276
    else
249
        to_copy = buf_size;
277
        to_copy = buf_size;
250
 
278
 
251
    IPC_SET_RETVAL(call->data, 0);
279
    IPC_SET_RETVAL(call->data, 0);
252
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
280
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
253
       same code in process_answer() can be used
281
       same code in process_answer() can be used
254
       (no way to distinguish method in answer) */
282
       (no way to distinguish method in answer) */
255
    IPC_SET_ARG1(call->data, uspace_addr);
283
    IPC_SET_ARG1(call->data, uspace_addr);
256
    IPC_SET_ARG2(call->data, to_copy);
284
    IPC_SET_ARG2(call->data, to_copy);
257
 
285
 
258
    IPC_SET_ARG3(call->data, total_bytes);
286
    IPC_SET_ARG3(call->data, total_bytes);
259
    call->buffer = buffer;
287
    call->buffer = buffer;
260
 
288
 
261
    ipc_answer(&TASK->kernel_box, call);
289
    ipc_answer(&TASK->kernel_box, call);
262
}
290
}
263
 
291
 
264
static void udebug_receive_regs_write(call_t *call)
292
static void udebug_receive_regs_write(call_t *call)
265
{
293
{
266
    thread_t *t;
294
    thread_t *t;
267
    void *uspace_data;
295
    void *uspace_data;
268
    unative_t to_copy;
296
    unative_t to_copy;
269
    int rc;
297
    int rc;
270
 
298
 
271
    uspace_data = (void *)IPC_GET_ARG3(call->data);
299
    uspace_data = (void *)IPC_GET_ARG3(call->data);
272
    to_copy = IPC_GET_ARG4(call->data);
300
    to_copy = IPC_GET_ARG4(call->data);
273
 
301
 
274
    t = (thread_t *) IPC_GET_ARG2(call->data);
302
    t = (thread_t *) IPC_GET_ARG2(call->data);
275
 
303
 
276
    rc = udebug_regs_write(t, call->buffer);
304
    rc = udebug_regs_write(t, call->buffer);
277
    if (rc < 0) {
305
    if (rc < 0) {
278
        IPC_SET_RETVAL(call->data, rc);
306
        IPC_SET_RETVAL(call->data, rc);
279
        ipc_answer(&TASK->kernel_box, call);
307
        ipc_answer(&TASK->kernel_box, call);
280
        return;
308
        return;
281
    }
309
    }
282
 
310
 
283
    /* Set answer values */
311
    /* Set answer values */
284
 
312
 
285
    IPC_SET_ARG1(call->data, to_copy);
313
    IPC_SET_ARG1(call->data, to_copy);
286
    IPC_SET_ARG2(call->data, sizeof(istate_t));
314
    IPC_SET_ARG2(call->data, sizeof(istate_t));
287
 
315
 
288
    IPC_SET_RETVAL(call->data, 0);
316
    IPC_SET_RETVAL(call->data, 0);
289
    free(call->buffer);
317
    free(call->buffer);
290
    call->buffer = NULL;
318
    call->buffer = NULL;
291
 
319
 
292
    ipc_answer(&TASK->kernel_box, call);
320
    ipc_answer(&TASK->kernel_box, call);
293
}
321
}
294
 
322
 
295
 
323
 
296
static void udebug_receive_mem_read(call_t *call)
324
static void udebug_receive_mem_read(call_t *call)
297
{
325
{
298
    unative_t uspace_dst;
326
    unative_t uspace_dst;
299
    unative_t uspace_src;
327
    unative_t uspace_src;
300
    unsigned size;
328
    unsigned size;
301
    void *buffer;
329
    void *buffer;
302
    int rc;
330
    int rc;
303
 
331
 
304
    uspace_dst = IPC_GET_ARG2(call->data);
332
    uspace_dst = IPC_GET_ARG2(call->data);
305
    uspace_src = IPC_GET_ARG3(call->data);
333
    uspace_src = IPC_GET_ARG3(call->data);
306
    size = IPC_GET_ARG4(call->data);
334
    size = IPC_GET_ARG4(call->data);
307
 
335
 
308
    rc = udebug_mem_read(uspace_src, size, &buffer);
336
    rc = udebug_mem_read(uspace_src, size, &buffer);
309
    if (rc < 0) {
337
    if (rc < 0) {
310
        IPC_SET_RETVAL(call->data, rc);
338
        IPC_SET_RETVAL(call->data, rc);
311
        ipc_answer(&TASK->kernel_box, call);
339
        ipc_answer(&TASK->kernel_box, call);
312
        return;
340
        return;
313
    }
341
    }
314
 
342
 
315
    IPC_SET_RETVAL(call->data, 0);
343
    IPC_SET_RETVAL(call->data, 0);
316
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
344
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
317
       same code in process_answer() can be used
345
       same code in process_answer() can be used
318
       (no way to distinguish method in answer) */
346
       (no way to distinguish method in answer) */
319
    IPC_SET_ARG1(call->data, uspace_dst);
347
    IPC_SET_ARG1(call->data, uspace_dst);
320
    IPC_SET_ARG2(call->data, size);
348
    IPC_SET_ARG2(call->data, size);
321
    call->buffer = buffer;
349
    call->buffer = buffer;
322
 
350
 
323
    ipc_answer(&TASK->kernel_box, call);
351
    ipc_answer(&TASK->kernel_box, call);
324
}
352
}
325
 
353
 
326
static void udebug_receive_mem_write(call_t *call)
354
static void udebug_receive_mem_write(call_t *call)
327
{
355
{
328
    unative_t uspace_dst;
356
    unative_t uspace_dst;
329
    unsigned size;
357
    unsigned size;
330
    int rc;
358
    int rc;
331
 
359
 
332
    klog_printf("udebug_receive_mem_write()");
360
    klog_printf("udebug_receive_mem_write()");
333
 
361
 
334
    uspace_dst = IPC_GET_ARG3(call->data);
362
    uspace_dst = IPC_GET_ARG3(call->data);
335
    size = IPC_GET_ARG4(call->data);
363
    size = IPC_GET_ARG4(call->data);
336
 
364
 
337
    rc = udebug_mem_write(uspace_dst, call->buffer, size);
365
    rc = udebug_mem_write(uspace_dst, call->buffer, size);
338
    if (rc < 0) {
366
    if (rc < 0) {
339
        IPC_SET_RETVAL(call->data, rc);
367
        IPC_SET_RETVAL(call->data, rc);
340
        ipc_answer(&TASK->kernel_box, call);
368
        ipc_answer(&TASK->kernel_box, call);
341
        return;
369
        return;
342
    }
370
    }
343
 
371
 
344
    IPC_SET_RETVAL(call->data, 0);
372
    IPC_SET_RETVAL(call->data, 0);
345
    free(call->buffer);
373
    free(call->buffer);
346
    call->buffer = NULL;
374
    call->buffer = NULL;
347
 
375
 
348
    ipc_answer(&TASK->kernel_box, call);
376
    ipc_answer(&TASK->kernel_box, call);
349
}
377
}
350
 
378
 
351
 
379
 
352
/**
380
/**
353
 * Handle a debug call received on the kernel answerbox.
381
 * Handle a debug call received on the kernel answerbox.
354
 *
382
 *
355
 * This is called by the kbox servicing thread.
383
 * This is called by the kbox servicing thread.
356
 */
384
 */
357
void udebug_call_receive(call_t *call)
385
void udebug_call_receive(call_t *call)
358
{
386
{
359
    int debug_method;
387
    int debug_method;
360
 
388
 
361
    debug_method = IPC_GET_ARG1(call->data);
389
    debug_method = IPC_GET_ARG1(call->data);
362
 
390
 
363
    if (debug_method != UDEBUG_M_BEGIN) {
391
    if (debug_method != UDEBUG_M_BEGIN) {
364
        /*
392
        /*
365
         * Verify that the sender is this task's debugger.
393
         * Verify that the sender is this task's debugger.
366
         * Note that this is the only thread that could change
394
         * Note that this is the only thread that could change
367
         * TASK->debugger. Therefore no locking is necessary
395
         * TASK->debugger. Therefore no locking is necessary
368
         * and the sender can be safely considered valid until
396
         * and the sender can be safely considered valid until
369
         * control exits this function.
397
         * control exits this function.
370
         */
398
         */
371
        if (TASK->debugger != call->sender) {
399
        if (TASK->debugger != call->sender) {
372
            IPC_SET_RETVAL(call->data, EINVAL);
400
            IPC_SET_RETVAL(call->data, EINVAL);
373
            ipc_answer(&TASK->kernel_box, call);
401
            ipc_answer(&TASK->kernel_box, call);
374
            return;
402
            return;
375
        }
403
        }
376
    }
404
    }
377
 
405
 
378
    switch (debug_method) {
406
    switch (debug_method) {
379
    case UDEBUG_M_BEGIN:
407
    case UDEBUG_M_BEGIN:
380
        udebug_receive_begin(call);
408
        udebug_receive_begin(call);
381
        break;
409
        break;
382
    case UDEBUG_M_END:
410
    case UDEBUG_M_END:
383
        udebug_receive_end(call);
411
        udebug_receive_end(call);
384
        break;
412
        break;
385
    case UDEBUG_M_GO:
413
    case UDEBUG_M_GO:
386
        udebug_receive_go(call);
414
        udebug_receive_go(call);
387
        break;
415
        break;
388
    case UDEBUG_M_THREAD_READ:
416
    case UDEBUG_M_THREAD_READ:
389
        udebug_receive_thread_read(call);
417
        udebug_receive_thread_read(call);
390
        break;
418
        break;
391
    case UDEBUG_M_ARGS_READ:
419
    case UDEBUG_M_ARGS_READ:
392
        udebug_receive_args_read(call);
420
        udebug_receive_args_read(call);
393
        break;
421
        break;
394
    case UDEBUG_M_REGS_READ:
422
    case UDEBUG_M_REGS_READ:
395
        udebug_receive_regs_read(call);
423
        udebug_receive_regs_read(call);
396
        break;
424
        break;
397
    case UDEBUG_M_REGS_WRITE:
425
    case UDEBUG_M_REGS_WRITE:
398
        udebug_receive_regs_write(call);
426
        udebug_receive_regs_write(call);
399
        break;
427
        break;
400
    case UDEBUG_M_MEM_READ:
428
    case UDEBUG_M_MEM_READ:
401
        udebug_receive_mem_read(call);
429
        udebug_receive_mem_read(call);
402
        break;
430
        break;
403
    case UDEBUG_M_MEM_WRITE:
431
    case UDEBUG_M_MEM_WRITE:
404
        udebug_receive_mem_write(call);
432
        udebug_receive_mem_write(call);
405
        break;
433
        break;
406
    }
434
    }
407
}
435
}
408
 
436
 
409
/** @}
437
/** @}
410
 */
438
 */
411
 
439