Subversion Repositories HelenOS

Rev

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

Rev 2897 Rev 2898
1
/*
1
/*
2
 * Copyright (c) 2008 Jiri Svoboda
2
 * Copyright (c) 2008 Jiri Svoboda
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
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
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.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
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
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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
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.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/** @addtogroup generic
29
/** @addtogroup generic
30
 * @{
30
 * @{
31
 */
31
 */
32
 
32
 
33
/**
33
/**
34
 * @file
34
 * @file
35
 * @brief   Udebug IPC message handling.
35
 * @brief   Udebug IPC message handling.
36
 */
36
 */
37
 
37
 
38
#include <console/klog.h>
38
#include <console/klog.h>
39
#include <proc/task.h>
39
#include <proc/task.h>
40
#include <proc/thread.h>
40
#include <proc/thread.h>
41
#include <arch.h>
41
#include <arch.h>
42
#include <errno.h>
42
#include <errno.h>
43
#include <ipc/ipc.h>
43
#include <ipc/ipc.h>
44
#include <syscall/copy.h>
44
#include <syscall/copy.h>
45
#include <udebug/udebug.h>
45
#include <udebug/udebug.h>
46
#include <udebug/udebug_ops.h>
46
#include <udebug/udebug_ops.h>
47
#include <udebug/udebug_ipc.h>
47
#include <udebug/udebug_ipc.h>
48
 
48
 
49
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)
50
{
50
{
51
    void *uspace_data;
51
    void *uspace_data;
52
    unative_t to_copy;
52
    unative_t to_copy;
53
    int rc;
53
    int rc;
54
    void *buffer;
54
    void *buffer;
55
 
55
 
56
    klog_printf("debug_regs_write()");
56
    klog_printf("debug_regs_write()");
57
 
57
 
58
    uspace_data = (void *)IPC_GET_ARG3(call->data);
58
    uspace_data = (void *)IPC_GET_ARG3(call->data);
59
    to_copy = IPC_GET_ARG4(call->data);
59
    to_copy = IPC_GET_ARG4(call->data);
60
    if (to_copy > sizeof(istate_t)) to_copy = sizeof(istate_t);
60
    if (to_copy > sizeof(istate_t)) to_copy = sizeof(istate_t);
61
 
61
 
62
    buffer = malloc(to_copy, 0);
62
    buffer = malloc(to_copy, 0);
63
    if (!buffer) return ENOMEM;
63
    if (!buffer) return ENOMEM;
64
 
64
 
65
    rc = copy_from_uspace(buffer, uspace_data, to_copy);
65
    rc = copy_from_uspace(buffer, uspace_data, to_copy);
66
    if (rc != 0) {
66
    if (rc != 0) {
67
        klog_printf("debug_regs_write() - copy failed");
67
        klog_printf("debug_regs_write() - copy failed");
68
        return rc;
68
        return rc;
69
    }
69
    }
70
 
70
 
71
    call->buffer = buffer;
71
    call->buffer = buffer;
72
 
72
 
73
    klog_printf(" - done");
73
    klog_printf(" - done");
74
    return 0;
74
    return 0;
75
}
75
}
76
 
76
 
77
static int udebug_rp_mem_write(call_t *call, phone_t *phone)
77
static int udebug_rp_mem_write(call_t *call, phone_t *phone)
78
{
78
{
79
    void *uspace_data;
79
    void *uspace_data;
80
    unative_t to_copy;
80
    unative_t to_copy;
81
    int rc;
81
    int rc;
82
    void *buffer;
82
    void *buffer;
83
 
83
 
84
    klog_printf("udebug_rp_mem_write()");
84
    klog_printf("udebug_rp_mem_write()");
85
 
85
 
86
    uspace_data = (void *)IPC_GET_ARG2(call->data);
86
    uspace_data = (void *)IPC_GET_ARG2(call->data);
87
    to_copy = IPC_GET_ARG4(call->data);
87
    to_copy = IPC_GET_ARG4(call->data);
88
 
88
 
89
    buffer = malloc(to_copy, 0);
89
    buffer = malloc(to_copy, 0);
90
    if (!buffer) return ENOMEM;
90
    if (!buffer) return ENOMEM;
91
 
91
 
92
    rc = copy_from_uspace(buffer, uspace_data, to_copy);
92
    rc = copy_from_uspace(buffer, uspace_data, to_copy);
93
    if (rc != 0) {
93
    if (rc != 0) {
94
        klog_printf(" - copy failed");
94
        klog_printf(" - copy failed");
95
        return rc;
95
        return rc;
96
    }
96
    }
97
 
97
 
98
    call->buffer = buffer;
98
    call->buffer = buffer;
99
 
99
 
100
    klog_printf(" - done");
100
    klog_printf(" - done");
101
    return 0;
101
    return 0;
102
}
102
}
103
 
103
 
104
 
104
 
105
int udebug_request_preprocess(call_t *call, phone_t *phone)
105
int udebug_request_preprocess(call_t *call, phone_t *phone)
106
{
106
{
107
    int rc;
107
    int rc;
108
 
108
 
109
    switch (IPC_GET_ARG1(call->data)) {
109
    switch (IPC_GET_ARG1(call->data)) {
110
    case UDEBUG_M_REGS_WRITE:
110
    case UDEBUG_M_REGS_WRITE:
111
        rc = udebug_rp_regs_write(call, phone);
111
        rc = udebug_rp_regs_write(call, phone);
112
        return rc;
112
        return rc;
113
    case UDEBUG_M_MEM_WRITE:
113
    case UDEBUG_M_MEM_WRITE:
114
        rc = udebug_rp_mem_write(call, phone);
114
        rc = udebug_rp_mem_write(call, phone);
115
        return rc;
115
        return rc;
116
    default:
116
    default:
117
        break;
117
        break;
118
    }
118
    }
119
 
119
 
120
    return 0;
120
    return 0;
121
}
121
}
122
 
122
 
123
static void udebug_receive_begin(call_t *call)
123
static void udebug_receive_begin(call_t *call)
124
{
124
{
125
    int rc;
125
    int rc;
126
 
126
 
127
    rc = udebug_begin(call);
127
    rc = udebug_begin(call);
128
    if (rc < 0) {
128
    if (rc < 0) {
129
        IPC_SET_RETVAL(call->data, rc);
129
        IPC_SET_RETVAL(call->data, rc);
130
        ipc_answer(&TASK->kernel_box, call);
130
        ipc_answer(&TASK->kernel_box, call);
131
        return;
131
        return;
132
    }
132
    }
133
 
133
 
134
    if (rc != 0) {
134
    if (rc != 0) {
135
        IPC_SET_RETVAL(call->data, 0);
135
        IPC_SET_RETVAL(call->data, 0);
136
        ipc_answer(&TASK->kernel_box, call);
136
        ipc_answer(&TASK->kernel_box, call);
137
    }
137
    }
138
}
138
}
139
 
139
 
140
static void udebug_receive_end(call_t *call)
140
static void udebug_receive_end(call_t *call)
141
{
141
{
142
    int rc;
142
    int rc;
143
 
143
 
144
    rc = udebug_end();
144
    rc = udebug_end();
145
 
145
 
146
    IPC_SET_RETVAL(call->data, rc);
146
    IPC_SET_RETVAL(call->data, rc);
147
    ipc_answer(&TASK->kernel_box, call);
147
    ipc_answer(&TASK->kernel_box, call);
148
}
148
}
149
 
149
 
150
static void udebug_receive_go(call_t *call)
150
static void udebug_receive_go(call_t *call)
151
{
151
{
152
    thread_t *t;
152
    thread_t *t;
153
    int rc;
153
    int rc;
154
 
154
 
155
    klog_printf("debug_go()");
155
    klog_printf("debug_go()");
156
 
156
 
157
    t = (thread_t *)IPC_GET_ARG2(call->data);
157
    t = (thread_t *)IPC_GET_ARG2(call->data);
158
 
158
 
159
    rc = udebug_go(t, call);
159
    rc = udebug_go(t, call);
160
    if (rc < 0) {
160
    if (rc < 0) {
161
        IPC_SET_RETVAL(call->data, rc);
161
        IPC_SET_RETVAL(call->data, rc);
162
        ipc_answer(&TASK->kernel_box, call);
162
        ipc_answer(&TASK->kernel_box, call);
163
        return;
163
        return;
164
    }
164
    }
165
}
165
}
166
 
166
 
-
 
167
static void udebug_receive_stop(call_t *call)
-
 
168
{
-
 
169
    thread_t *t;
-
 
170
    int rc;
-
 
171
 
-
 
172
    klog_printf("debug_stop()");
-
 
173
 
-
 
174
    t = (thread_t *)IPC_GET_ARG2(call->data);
-
 
175
 
-
 
176
    rc = udebug_stop(t, call);
-
 
177
    IPC_SET_RETVAL(call->data, rc);
-
 
178
    ipc_answer(&TASK->kernel_box, call);
-
 
179
}
167
 
180
 
168
static void udebug_receive_thread_read(call_t *call)
181
static void udebug_receive_thread_read(call_t *call)
169
{
182
{
170
    unative_t uspace_addr;
183
    unative_t uspace_addr;
171
    unative_t to_copy;
184
    unative_t to_copy;
172
    unsigned total_bytes;
185
    unsigned total_bytes;
173
    unsigned buf_size;
186
    unsigned buf_size;
174
    void *buffer;
187
    void *buffer;
175
    size_t n;
188
    size_t n;
176
    int rc;
189
    int rc;
177
 
190
 
178
    uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */
191
    uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */
179
    buf_size = IPC_GET_ARG3(call->data);    /* Dest. buffer size */
192
    buf_size = IPC_GET_ARG3(call->data);    /* Dest. buffer size */
180
 
193
 
181
    /*
194
    /*
182
     * Read thread list. Variable n will be filled with actual number
195
     * Read thread list. Variable n will be filled with actual number
183
     * of threads times thread-id size.
196
     * of threads times thread-id size.
184
     */
197
     */
185
    rc = udebug_thread_read(&buffer, buf_size, &n);
198
    rc = udebug_thread_read(&buffer, buf_size, &n);
186
    if (rc < 0) {
199
    if (rc < 0) {
187
        IPC_SET_RETVAL(call->data, rc);
200
        IPC_SET_RETVAL(call->data, rc);
188
        ipc_answer(&TASK->kernel_box, call);
201
        ipc_answer(&TASK->kernel_box, call);
189
        return;
202
        return;
190
    }
203
    }
191
 
204
 
192
    total_bytes = n;
205
    total_bytes = n;
193
 
206
 
194
    /* Copy MAX(buf_size, total_bytes) bytes */
207
    /* Copy MAX(buf_size, total_bytes) bytes */
195
 
208
 
196
    if (buf_size > total_bytes)
209
    if (buf_size > total_bytes)
197
        to_copy = total_bytes;
210
        to_copy = total_bytes;
198
    else
211
    else
199
        to_copy = buf_size;
212
        to_copy = buf_size;
200
 
213
 
201
    /*
214
    /*
202
     * Make use of call->buffer to transfer data to caller's userspace
215
     * Make use of call->buffer to transfer data to caller's userspace
203
     */
216
     */
204
 
217
 
205
    IPC_SET_RETVAL(call->data, 0);
218
    IPC_SET_RETVAL(call->data, 0);
206
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
219
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
207
       same code in process_answer() can be used
220
       same code in process_answer() can be used
208
       (no way to distinguish method in answer) */
221
       (no way to distinguish method in answer) */
209
    IPC_SET_ARG1(call->data, uspace_addr);
222
    IPC_SET_ARG1(call->data, uspace_addr);
210
    IPC_SET_ARG2(call->data, to_copy);
223
    IPC_SET_ARG2(call->data, to_copy);
211
 
224
 
212
    IPC_SET_ARG3(call->data, total_bytes);
225
    IPC_SET_ARG3(call->data, total_bytes);
213
    call->buffer = buffer;
226
    call->buffer = buffer;
214
 
227
 
215
    ipc_answer(&TASK->kernel_box, call);
228
    ipc_answer(&TASK->kernel_box, call);
216
}
229
}
217
 
230
 
218
static void udebug_receive_args_read(call_t *call)
231
static void udebug_receive_args_read(call_t *call)
219
{
232
{
220
    thread_t *t;
233
    thread_t *t;
221
    unative_t uspace_addr;
234
    unative_t uspace_addr;
222
    int rc;
235
    int rc;
223
    void *buffer;
236
    void *buffer;
224
 
237
 
225
    t = (thread_t *)IPC_GET_ARG2(call->data);
238
    t = (thread_t *)IPC_GET_ARG2(call->data);
226
 
239
 
227
    rc = udebug_args_read(t, &buffer);
240
    rc = udebug_args_read(t, &buffer);
228
    if (rc != EOK) {
241
    if (rc != EOK) {
229
        IPC_SET_RETVAL(call->data, rc);
242
        IPC_SET_RETVAL(call->data, rc);
230
        ipc_answer(&TASK->kernel_box, call);
243
        ipc_answer(&TASK->kernel_box, call);
231
        return;
244
        return;
232
    }
245
    }
233
 
246
 
234
    /*
247
    /*
235
     * Make use of call->buffer to transfer data to caller's userspace
248
     * Make use of call->buffer to transfer data to caller's userspace
236
     */
249
     */
237
 
250
 
238
    uspace_addr = IPC_GET_ARG3(call->data);
251
    uspace_addr = IPC_GET_ARG3(call->data);
239
 
252
 
240
    IPC_SET_RETVAL(call->data, 0);
253
    IPC_SET_RETVAL(call->data, 0);
241
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
254
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
242
       same code in process_answer() can be used
255
       same code in process_answer() can be used
243
       (no way to distinguish method in answer) */
256
       (no way to distinguish method in answer) */
244
    IPC_SET_ARG1(call->data, uspace_addr);
257
    IPC_SET_ARG1(call->data, uspace_addr);
245
    IPC_SET_ARG2(call->data, 6 * sizeof(unative_t));
258
    IPC_SET_ARG2(call->data, 6 * sizeof(unative_t));
246
    call->buffer = buffer;
259
    call->buffer = buffer;
247
 
260
 
248
    ipc_answer(&TASK->kernel_box, call);
261
    ipc_answer(&TASK->kernel_box, call);
249
}
262
}
250
 
263
 
251
static void udebug_receive_regs_read(call_t *call)
264
static void udebug_receive_regs_read(call_t *call)
252
{
265
{
253
    thread_t *t;
266
    thread_t *t;
254
    unative_t uspace_addr;
267
    unative_t uspace_addr;
255
    unative_t to_copy;
268
    unative_t to_copy;
256
    unative_t buf_size;
269
    unative_t buf_size;
257
    unative_t total_bytes;
270
    unative_t total_bytes;
258
    void *buffer;
271
    void *buffer;
259
    int rc;
272
    int rc;
260
    size_t n;
273
    size_t n;
261
 
274
 
262
    klog_printf("debug_regs_read()");
275
    klog_printf("debug_regs_read()");
263
 
276
 
264
    t = (thread_t *) IPC_GET_ARG2(call->data);
277
    t = (thread_t *) IPC_GET_ARG2(call->data);
265
 
278
 
266
    rc = udebug_regs_read(t, &buffer, &n);
279
    rc = udebug_regs_read(t, &buffer, &n);
267
    if (rc < 0) {
280
    if (rc < 0) {
268
        IPC_SET_RETVAL(call->data, rc);
281
        IPC_SET_RETVAL(call->data, rc);
269
        ipc_answer(&TASK->kernel_box, call);
282
        ipc_answer(&TASK->kernel_box, call);
270
        return;
283
        return;
271
    }
284
    }
272
 
285
 
273
    /*
286
    /*
274
     * Make use of call->buffer to transfer data to caller's userspace
287
     * Make use of call->buffer to transfer data to caller's userspace
275
     */
288
     */
276
 
289
 
277
    uspace_addr = IPC_GET_ARG3(call->data);
290
    uspace_addr = IPC_GET_ARG3(call->data);
278
    buf_size = IPC_GET_ARG4(call->data);
291
    buf_size = IPC_GET_ARG4(call->data);
279
 
292
 
280
    total_bytes = n;
293
    total_bytes = n;
281
 
294
 
282
    if (buf_size > total_bytes)
295
    if (buf_size > total_bytes)
283
        to_copy = total_bytes;
296
        to_copy = total_bytes;
284
    else
297
    else
285
        to_copy = buf_size;
298
        to_copy = buf_size;
286
 
299
 
287
    IPC_SET_RETVAL(call->data, 0);
300
    IPC_SET_RETVAL(call->data, 0);
288
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
301
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
289
       same code in process_answer() can be used
302
       same code in process_answer() can be used
290
       (no way to distinguish method in answer) */
303
       (no way to distinguish method in answer) */
291
    IPC_SET_ARG1(call->data, uspace_addr);
304
    IPC_SET_ARG1(call->data, uspace_addr);
292
    IPC_SET_ARG2(call->data, to_copy);
305
    IPC_SET_ARG2(call->data, to_copy);
293
 
306
 
294
    IPC_SET_ARG3(call->data, total_bytes);
307
    IPC_SET_ARG3(call->data, total_bytes);
295
    call->buffer = buffer;
308
    call->buffer = buffer;
296
 
309
 
297
    ipc_answer(&TASK->kernel_box, call);
310
    ipc_answer(&TASK->kernel_box, call);
298
}
311
}
299
 
312
 
300
static void udebug_receive_regs_write(call_t *call)
313
static void udebug_receive_regs_write(call_t *call)
301
{
314
{
302
    thread_t *t;
315
    thread_t *t;
303
    void *uspace_data;
316
    void *uspace_data;
304
    unative_t to_copy;
317
    unative_t to_copy;
305
    int rc;
318
    int rc;
306
 
319
 
307
    uspace_data = (void *)IPC_GET_ARG3(call->data);
320
    uspace_data = (void *)IPC_GET_ARG3(call->data);
308
    to_copy = IPC_GET_ARG4(call->data);
321
    to_copy = IPC_GET_ARG4(call->data);
309
 
322
 
310
    t = (thread_t *) IPC_GET_ARG2(call->data);
323
    t = (thread_t *) IPC_GET_ARG2(call->data);
311
 
324
 
312
    rc = udebug_regs_write(t, call->buffer);
325
    rc = udebug_regs_write(t, call->buffer);
313
    if (rc < 0) {
326
    if (rc < 0) {
314
        IPC_SET_RETVAL(call->data, rc);
327
        IPC_SET_RETVAL(call->data, rc);
315
        ipc_answer(&TASK->kernel_box, call);
328
        ipc_answer(&TASK->kernel_box, call);
316
        return;
329
        return;
317
    }
330
    }
318
 
331
 
319
    /* Set answer values */
332
    /* Set answer values */
320
 
333
 
321
    IPC_SET_ARG1(call->data, to_copy);
334
    IPC_SET_ARG1(call->data, to_copy);
322
    IPC_SET_ARG2(call->data, sizeof(istate_t));
335
    IPC_SET_ARG2(call->data, sizeof(istate_t));
323
 
336
 
324
    IPC_SET_RETVAL(call->data, 0);
337
    IPC_SET_RETVAL(call->data, 0);
325
    free(call->buffer);
338
    free(call->buffer);
326
    call->buffer = NULL;
339
    call->buffer = NULL;
327
 
340
 
328
    ipc_answer(&TASK->kernel_box, call);
341
    ipc_answer(&TASK->kernel_box, call);
329
}
342
}
330
 
343
 
331
 
344
 
332
static void udebug_receive_mem_read(call_t *call)
345
static void udebug_receive_mem_read(call_t *call)
333
{
346
{
334
    unative_t uspace_dst;
347
    unative_t uspace_dst;
335
    unative_t uspace_src;
348
    unative_t uspace_src;
336
    unsigned size;
349
    unsigned size;
337
    void *buffer;
350
    void *buffer;
338
    int rc;
351
    int rc;
339
 
352
 
340
    uspace_dst = IPC_GET_ARG2(call->data);
353
    uspace_dst = IPC_GET_ARG2(call->data);
341
    uspace_src = IPC_GET_ARG3(call->data);
354
    uspace_src = IPC_GET_ARG3(call->data);
342
    size = IPC_GET_ARG4(call->data);
355
    size = IPC_GET_ARG4(call->data);
343
 
356
 
344
    rc = udebug_mem_read(uspace_src, size, &buffer);
357
    rc = udebug_mem_read(uspace_src, size, &buffer);
345
    if (rc < 0) {
358
    if (rc < 0) {
346
        IPC_SET_RETVAL(call->data, rc);
359
        IPC_SET_RETVAL(call->data, rc);
347
        ipc_answer(&TASK->kernel_box, call);
360
        ipc_answer(&TASK->kernel_box, call);
348
        return;
361
        return;
349
    }
362
    }
350
 
363
 
351
    IPC_SET_RETVAL(call->data, 0);
364
    IPC_SET_RETVAL(call->data, 0);
352
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
365
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
353
       same code in process_answer() can be used
366
       same code in process_answer() can be used
354
       (no way to distinguish method in answer) */
367
       (no way to distinguish method in answer) */
355
    IPC_SET_ARG1(call->data, uspace_dst);
368
    IPC_SET_ARG1(call->data, uspace_dst);
356
    IPC_SET_ARG2(call->data, size);
369
    IPC_SET_ARG2(call->data, size);
357
    call->buffer = buffer;
370
    call->buffer = buffer;
358
 
371
 
359
    ipc_answer(&TASK->kernel_box, call);
372
    ipc_answer(&TASK->kernel_box, call);
360
}
373
}
361
 
374
 
362
static void udebug_receive_mem_write(call_t *call)
375
static void udebug_receive_mem_write(call_t *call)
363
{
376
{
364
    unative_t uspace_dst;
377
    unative_t uspace_dst;
365
    unsigned size;
378
    unsigned size;
366
    int rc;
379
    int rc;
367
 
380
 
368
    klog_printf("udebug_receive_mem_write()");
381
    klog_printf("udebug_receive_mem_write()");
369
 
382
 
370
    uspace_dst = IPC_GET_ARG3(call->data);
383
    uspace_dst = IPC_GET_ARG3(call->data);
371
    size = IPC_GET_ARG4(call->data);
384
    size = IPC_GET_ARG4(call->data);
372
 
385
 
373
    rc = udebug_mem_write(uspace_dst, call->buffer, size);
386
    rc = udebug_mem_write(uspace_dst, call->buffer, size);
374
    if (rc < 0) {
387
    if (rc < 0) {
375
        IPC_SET_RETVAL(call->data, rc);
388
        IPC_SET_RETVAL(call->data, rc);
376
        ipc_answer(&TASK->kernel_box, call);
389
        ipc_answer(&TASK->kernel_box, call);
377
        return;
390
        return;
378
    }
391
    }
379
 
392
 
380
    IPC_SET_RETVAL(call->data, 0);
393
    IPC_SET_RETVAL(call->data, 0);
381
    free(call->buffer);
394
    free(call->buffer);
382
    call->buffer = NULL;
395
    call->buffer = NULL;
383
 
396
 
384
    ipc_answer(&TASK->kernel_box, call);
397
    ipc_answer(&TASK->kernel_box, call);
385
}
398
}
386
 
399
 
387
 
400
 
388
/**
401
/**
389
 * Handle a debug call received on the kernel answerbox.
402
 * Handle a debug call received on the kernel answerbox.
390
 *
403
 *
391
 * This is called by the kbox servicing thread.
404
 * This is called by the kbox servicing thread.
392
 */
405
 */
393
void udebug_call_receive(call_t *call)
406
void udebug_call_receive(call_t *call)
394
{
407
{
395
    int debug_method;
408
    int debug_method;
396
 
409
 
397
    debug_method = IPC_GET_ARG1(call->data);
410
    debug_method = IPC_GET_ARG1(call->data);
398
 
411
 
399
    if (debug_method != UDEBUG_M_BEGIN) {
412
    if (debug_method != UDEBUG_M_BEGIN) {
400
        /*
413
        /*
401
         * Verify that the sender is this task's debugger.
414
         * Verify that the sender is this task's debugger.
402
         * Note that this is the only thread that could change
415
         * Note that this is the only thread that could change
403
         * TASK->debugger. Therefore no locking is necessary
416
         * TASK->debugger. Therefore no locking is necessary
404
         * and the sender can be safely considered valid until
417
         * and the sender can be safely considered valid until
405
         * control exits this function.
418
         * control exits this function.
406
         */
419
         */
407
        if (TASK->debugger != call->sender) {
420
        if (TASK->debugger != call->sender) {
408
            IPC_SET_RETVAL(call->data, EINVAL);
421
            IPC_SET_RETVAL(call->data, EINVAL);
409
            ipc_answer(&TASK->kernel_box, call);
422
            ipc_answer(&TASK->kernel_box, call);
410
            return;
423
            return;
411
        }
424
        }
412
    }
425
    }
413
 
426
 
414
    switch (debug_method) {
427
    switch (debug_method) {
415
    case UDEBUG_M_BEGIN:
428
    case UDEBUG_M_BEGIN:
416
        udebug_receive_begin(call);
429
        udebug_receive_begin(call);
417
        break;
430
        break;
418
    case UDEBUG_M_END:
431
    case UDEBUG_M_END:
419
        udebug_receive_end(call);
432
        udebug_receive_end(call);
420
        break;
433
        break;
421
    case UDEBUG_M_GO:
434
    case UDEBUG_M_GO:
422
        udebug_receive_go(call);
435
        udebug_receive_go(call);
423
        break;
436
        break;
-
 
437
    case UDEBUG_M_STOP:
-
 
438
        udebug_receive_stop(call);
-
 
439
        break;
424
    case UDEBUG_M_THREAD_READ:
440
    case UDEBUG_M_THREAD_READ:
425
        udebug_receive_thread_read(call);
441
        udebug_receive_thread_read(call);
426
        break;
442
        break;
427
    case UDEBUG_M_ARGS_READ:
443
    case UDEBUG_M_ARGS_READ:
428
        udebug_receive_args_read(call);
444
        udebug_receive_args_read(call);
429
        break;
445
        break;
430
    case UDEBUG_M_REGS_READ:
446
    case UDEBUG_M_REGS_READ:
431
        udebug_receive_regs_read(call);
447
        udebug_receive_regs_read(call);
432
        break;
448
        break;
433
    case UDEBUG_M_REGS_WRITE:
449
    case UDEBUG_M_REGS_WRITE:
434
        udebug_receive_regs_write(call);
450
        udebug_receive_regs_write(call);
435
        break;
451
        break;
436
    case UDEBUG_M_MEM_READ:
452
    case UDEBUG_M_MEM_READ:
437
        udebug_receive_mem_read(call);
453
        udebug_receive_mem_read(call);
438
        break;
454
        break;
439
    case UDEBUG_M_MEM_WRITE:
455
    case UDEBUG_M_MEM_WRITE:
440
        udebug_receive_mem_write(call);
456
        udebug_receive_mem_write(call);
441
        break;
457
        break;
442
    }
458
    }
443
}
459
}
444
 
460
 
445
/** @}
461
/** @}
446
 */
462
 */
447
 
463