Subversion Repositories HelenOS

Rev

Rev 3014 | Rev 3471 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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