Subversion Repositories HelenOS

Rev

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

Rev 2898 Rev 2899
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_set_evmask(call_t *call)
-
 
151
{
-
 
152
    int rc;
-
 
153
    udebug_evmask_t mask;
-
 
154
 
-
 
155
    mask = IPC_GET_ARG2(call->data);
-
 
156
    rc = udebug_set_evmask(mask);
-
 
157
 
-
 
158
    IPC_SET_RETVAL(call->data, rc);
-
 
159
    ipc_answer(&TASK->kernel_box, call);
-
 
160
}
-
 
161
 
-
 
162
 
150
static void udebug_receive_go(call_t *call)
163
static void udebug_receive_go(call_t *call)
151
{
164
{
152
    thread_t *t;
165
    thread_t *t;
153
    int rc;
166
    int rc;
154
 
167
 
155
    klog_printf("debug_go()");
168
    klog_printf("debug_go()");
156
 
169
 
157
    t = (thread_t *)IPC_GET_ARG2(call->data);
170
    t = (thread_t *)IPC_GET_ARG2(call->data);
158
 
171
 
159
    rc = udebug_go(t, call);
172
    rc = udebug_go(t, call);
160
    if (rc < 0) {
173
    if (rc < 0) {
161
        IPC_SET_RETVAL(call->data, rc);
174
        IPC_SET_RETVAL(call->data, rc);
162
        ipc_answer(&TASK->kernel_box, call);
175
        ipc_answer(&TASK->kernel_box, call);
163
        return;
176
        return;
164
    }
177
    }
165
}
178
}
166
 
179
 
167
static void udebug_receive_stop(call_t *call)
180
static void udebug_receive_stop(call_t *call)
168
{
181
{
169
    thread_t *t;
182
    thread_t *t;
170
    int rc;
183
    int rc;
171
 
184
 
172
    klog_printf("debug_stop()");
185
    klog_printf("debug_stop()");
173
 
186
 
174
    t = (thread_t *)IPC_GET_ARG2(call->data);
187
    t = (thread_t *)IPC_GET_ARG2(call->data);
175
 
188
 
176
    rc = udebug_stop(t, call);
189
    rc = udebug_stop(t, call);
177
    IPC_SET_RETVAL(call->data, rc);
190
    IPC_SET_RETVAL(call->data, rc);
178
    ipc_answer(&TASK->kernel_box, call);
191
    ipc_answer(&TASK->kernel_box, call);
179
}
192
}
180
 
193
 
181
static void udebug_receive_thread_read(call_t *call)
194
static void udebug_receive_thread_read(call_t *call)
182
{
195
{
183
    unative_t uspace_addr;
196
    unative_t uspace_addr;
184
    unative_t to_copy;
197
    unative_t to_copy;
185
    unsigned total_bytes;
198
    unsigned total_bytes;
186
    unsigned buf_size;
199
    unsigned buf_size;
187
    void *buffer;
200
    void *buffer;
188
    size_t n;
201
    size_t n;
189
    int rc;
202
    int rc;
190
 
203
 
191
    uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */
204
    uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */
192
    buf_size = IPC_GET_ARG3(call->data);    /* Dest. buffer size */
205
    buf_size = IPC_GET_ARG3(call->data);    /* Dest. buffer size */
193
 
206
 
194
    /*
207
    /*
195
     * Read thread list. Variable n will be filled with actual number
208
     * Read thread list. Variable n will be filled with actual number
196
     * of threads times thread-id size.
209
     * of threads times thread-id size.
197
     */
210
     */
198
    rc = udebug_thread_read(&buffer, buf_size, &n);
211
    rc = udebug_thread_read(&buffer, buf_size, &n);
199
    if (rc < 0) {
212
    if (rc < 0) {
200
        IPC_SET_RETVAL(call->data, rc);
213
        IPC_SET_RETVAL(call->data, rc);
201
        ipc_answer(&TASK->kernel_box, call);
214
        ipc_answer(&TASK->kernel_box, call);
202
        return;
215
        return;
203
    }
216
    }
204
 
217
 
205
    total_bytes = n;
218
    total_bytes = n;
206
 
219
 
207
    /* Copy MAX(buf_size, total_bytes) bytes */
220
    /* Copy MAX(buf_size, total_bytes) bytes */
208
 
221
 
209
    if (buf_size > total_bytes)
222
    if (buf_size > total_bytes)
210
        to_copy = total_bytes;
223
        to_copy = total_bytes;
211
    else
224
    else
212
        to_copy = buf_size;
225
        to_copy = buf_size;
213
 
226
 
214
    /*
227
    /*
215
     * Make use of call->buffer to transfer data to caller's userspace
228
     * Make use of call->buffer to transfer data to caller's userspace
216
     */
229
     */
217
 
230
 
218
    IPC_SET_RETVAL(call->data, 0);
231
    IPC_SET_RETVAL(call->data, 0);
219
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
232
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
220
       same code in process_answer() can be used
233
       same code in process_answer() can be used
221
       (no way to distinguish method in answer) */
234
       (no way to distinguish method in answer) */
222
    IPC_SET_ARG1(call->data, uspace_addr);
235
    IPC_SET_ARG1(call->data, uspace_addr);
223
    IPC_SET_ARG2(call->data, to_copy);
236
    IPC_SET_ARG2(call->data, to_copy);
224
 
237
 
225
    IPC_SET_ARG3(call->data, total_bytes);
238
    IPC_SET_ARG3(call->data, total_bytes);
226
    call->buffer = buffer;
239
    call->buffer = buffer;
227
 
240
 
228
    ipc_answer(&TASK->kernel_box, call);
241
    ipc_answer(&TASK->kernel_box, call);
229
}
242
}
230
 
243
 
231
static void udebug_receive_args_read(call_t *call)
244
static void udebug_receive_args_read(call_t *call)
232
{
245
{
233
    thread_t *t;
246
    thread_t *t;
234
    unative_t uspace_addr;
247
    unative_t uspace_addr;
235
    int rc;
248
    int rc;
236
    void *buffer;
249
    void *buffer;
237
 
250
 
238
    t = (thread_t *)IPC_GET_ARG2(call->data);
251
    t = (thread_t *)IPC_GET_ARG2(call->data);
239
 
252
 
240
    rc = udebug_args_read(t, &buffer);
253
    rc = udebug_args_read(t, &buffer);
241
    if (rc != EOK) {
254
    if (rc != EOK) {
242
        IPC_SET_RETVAL(call->data, rc);
255
        IPC_SET_RETVAL(call->data, rc);
243
        ipc_answer(&TASK->kernel_box, call);
256
        ipc_answer(&TASK->kernel_box, call);
244
        return;
257
        return;
245
    }
258
    }
246
 
259
 
247
    /*
260
    /*
248
     * Make use of call->buffer to transfer data to caller's userspace
261
     * Make use of call->buffer to transfer data to caller's userspace
249
     */
262
     */
250
 
263
 
251
    uspace_addr = IPC_GET_ARG3(call->data);
264
    uspace_addr = IPC_GET_ARG3(call->data);
252
 
265
 
253
    IPC_SET_RETVAL(call->data, 0);
266
    IPC_SET_RETVAL(call->data, 0);
254
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
267
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
255
       same code in process_answer() can be used
268
       same code in process_answer() can be used
256
       (no way to distinguish method in answer) */
269
       (no way to distinguish method in answer) */
257
    IPC_SET_ARG1(call->data, uspace_addr);
270
    IPC_SET_ARG1(call->data, uspace_addr);
258
    IPC_SET_ARG2(call->data, 6 * sizeof(unative_t));
271
    IPC_SET_ARG2(call->data, 6 * sizeof(unative_t));
259
    call->buffer = buffer;
272
    call->buffer = buffer;
260
 
273
 
261
    ipc_answer(&TASK->kernel_box, call);
274
    ipc_answer(&TASK->kernel_box, call);
262
}
275
}
263
 
276
 
264
static void udebug_receive_regs_read(call_t *call)
277
static void udebug_receive_regs_read(call_t *call)
265
{
278
{
266
    thread_t *t;
279
    thread_t *t;
267
    unative_t uspace_addr;
280
    unative_t uspace_addr;
268
    unative_t to_copy;
281
    unative_t to_copy;
269
    unative_t buf_size;
282
    unative_t buf_size;
270
    unative_t total_bytes;
283
    unative_t total_bytes;
271
    void *buffer;
284
    void *buffer;
272
    int rc;
285
    int rc;
273
    size_t n;
286
    size_t n;
274
 
287
 
275
    klog_printf("debug_regs_read()");
288
    klog_printf("debug_regs_read()");
276
 
289
 
277
    t = (thread_t *) IPC_GET_ARG2(call->data);
290
    t = (thread_t *) IPC_GET_ARG2(call->data);
278
 
291
 
279
    rc = udebug_regs_read(t, &buffer, &n);
292
    rc = udebug_regs_read(t, &buffer, &n);
280
    if (rc < 0) {
293
    if (rc < 0) {
281
        IPC_SET_RETVAL(call->data, rc);
294
        IPC_SET_RETVAL(call->data, rc);
282
        ipc_answer(&TASK->kernel_box, call);
295
        ipc_answer(&TASK->kernel_box, call);
283
        return;
296
        return;
284
    }
297
    }
285
 
298
 
286
    /*
299
    /*
287
     * Make use of call->buffer to transfer data to caller's userspace
300
     * Make use of call->buffer to transfer data to caller's userspace
288
     */
301
     */
289
 
302
 
290
    uspace_addr = IPC_GET_ARG3(call->data);
303
    uspace_addr = IPC_GET_ARG3(call->data);
291
    buf_size = IPC_GET_ARG4(call->data);
304
    buf_size = IPC_GET_ARG4(call->data);
292
 
305
 
293
    total_bytes = n;
306
    total_bytes = n;
294
 
307
 
295
    if (buf_size > total_bytes)
308
    if (buf_size > total_bytes)
296
        to_copy = total_bytes;
309
        to_copy = total_bytes;
297
    else
310
    else
298
        to_copy = buf_size;
311
        to_copy = buf_size;
299
 
312
 
300
    IPC_SET_RETVAL(call->data, 0);
313
    IPC_SET_RETVAL(call->data, 0);
301
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
314
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
302
       same code in process_answer() can be used
315
       same code in process_answer() can be used
303
       (no way to distinguish method in answer) */
316
       (no way to distinguish method in answer) */
304
    IPC_SET_ARG1(call->data, uspace_addr);
317
    IPC_SET_ARG1(call->data, uspace_addr);
305
    IPC_SET_ARG2(call->data, to_copy);
318
    IPC_SET_ARG2(call->data, to_copy);
306
 
319
 
307
    IPC_SET_ARG3(call->data, total_bytes);
320
    IPC_SET_ARG3(call->data, total_bytes);
308
    call->buffer = buffer;
321
    call->buffer = buffer;
309
 
322
 
310
    ipc_answer(&TASK->kernel_box, call);
323
    ipc_answer(&TASK->kernel_box, call);
311
}
324
}
312
 
325
 
313
static void udebug_receive_regs_write(call_t *call)
326
static void udebug_receive_regs_write(call_t *call)
314
{
327
{
315
    thread_t *t;
328
    thread_t *t;
316
    void *uspace_data;
329
    void *uspace_data;
317
    unative_t to_copy;
330
    unative_t to_copy;
318
    int rc;
331
    int rc;
319
 
332
 
320
    uspace_data = (void *)IPC_GET_ARG3(call->data);
333
    uspace_data = (void *)IPC_GET_ARG3(call->data);
321
    to_copy = IPC_GET_ARG4(call->data);
334
    to_copy = IPC_GET_ARG4(call->data);
322
 
335
 
323
    t = (thread_t *) IPC_GET_ARG2(call->data);
336
    t = (thread_t *) IPC_GET_ARG2(call->data);
324
 
337
 
325
    rc = udebug_regs_write(t, call->buffer);
338
    rc = udebug_regs_write(t, call->buffer);
326
    if (rc < 0) {
339
    if (rc < 0) {
327
        IPC_SET_RETVAL(call->data, rc);
340
        IPC_SET_RETVAL(call->data, rc);
328
        ipc_answer(&TASK->kernel_box, call);
341
        ipc_answer(&TASK->kernel_box, call);
329
        return;
342
        return;
330
    }
343
    }
331
 
344
 
332
    /* Set answer values */
345
    /* Set answer values */
333
 
346
 
334
    IPC_SET_ARG1(call->data, to_copy);
347
    IPC_SET_ARG1(call->data, to_copy);
335
    IPC_SET_ARG2(call->data, sizeof(istate_t));
348
    IPC_SET_ARG2(call->data, sizeof(istate_t));
336
 
349
 
337
    IPC_SET_RETVAL(call->data, 0);
350
    IPC_SET_RETVAL(call->data, 0);
338
    free(call->buffer);
351
    free(call->buffer);
339
    call->buffer = NULL;
352
    call->buffer = NULL;
340
 
353
 
341
    ipc_answer(&TASK->kernel_box, call);
354
    ipc_answer(&TASK->kernel_box, call);
342
}
355
}
343
 
356
 
344
 
357
 
345
static void udebug_receive_mem_read(call_t *call)
358
static void udebug_receive_mem_read(call_t *call)
346
{
359
{
347
    unative_t uspace_dst;
360
    unative_t uspace_dst;
348
    unative_t uspace_src;
361
    unative_t uspace_src;
349
    unsigned size;
362
    unsigned size;
350
    void *buffer;
363
    void *buffer;
351
    int rc;
364
    int rc;
352
 
365
 
353
    uspace_dst = IPC_GET_ARG2(call->data);
366
    uspace_dst = IPC_GET_ARG2(call->data);
354
    uspace_src = IPC_GET_ARG3(call->data);
367
    uspace_src = IPC_GET_ARG3(call->data);
355
    size = IPC_GET_ARG4(call->data);
368
    size = IPC_GET_ARG4(call->data);
356
 
369
 
357
    rc = udebug_mem_read(uspace_src, size, &buffer);
370
    rc = udebug_mem_read(uspace_src, size, &buffer);
358
    if (rc < 0) {
371
    if (rc < 0) {
359
        IPC_SET_RETVAL(call->data, rc);
372
        IPC_SET_RETVAL(call->data, rc);
360
        ipc_answer(&TASK->kernel_box, call);
373
        ipc_answer(&TASK->kernel_box, call);
361
        return;
374
        return;
362
    }
375
    }
363
 
376
 
364
    IPC_SET_RETVAL(call->data, 0);
377
    IPC_SET_RETVAL(call->data, 0);
365
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
378
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
366
       same code in process_answer() can be used
379
       same code in process_answer() can be used
367
       (no way to distinguish method in answer) */
380
       (no way to distinguish method in answer) */
368
    IPC_SET_ARG1(call->data, uspace_dst);
381
    IPC_SET_ARG1(call->data, uspace_dst);
369
    IPC_SET_ARG2(call->data, size);
382
    IPC_SET_ARG2(call->data, size);
370
    call->buffer = buffer;
383
    call->buffer = buffer;
371
 
384
 
372
    ipc_answer(&TASK->kernel_box, call);
385
    ipc_answer(&TASK->kernel_box, call);
373
}
386
}
374
 
387
 
375
static void udebug_receive_mem_write(call_t *call)
388
static void udebug_receive_mem_write(call_t *call)
376
{
389
{
377
    unative_t uspace_dst;
390
    unative_t uspace_dst;
378
    unsigned size;
391
    unsigned size;
379
    int rc;
392
    int rc;
380
 
393
 
381
    klog_printf("udebug_receive_mem_write()");
394
    klog_printf("udebug_receive_mem_write()");
382
 
395
 
383
    uspace_dst = IPC_GET_ARG3(call->data);
396
    uspace_dst = IPC_GET_ARG3(call->data);
384
    size = IPC_GET_ARG4(call->data);
397
    size = IPC_GET_ARG4(call->data);
385
 
398
 
386
    rc = udebug_mem_write(uspace_dst, call->buffer, size);
399
    rc = udebug_mem_write(uspace_dst, call->buffer, size);
387
    if (rc < 0) {
400
    if (rc < 0) {
388
        IPC_SET_RETVAL(call->data, rc);
401
        IPC_SET_RETVAL(call->data, rc);
389
        ipc_answer(&TASK->kernel_box, call);
402
        ipc_answer(&TASK->kernel_box, call);
390
        return;
403
        return;
391
    }
404
    }
392
 
405
 
393
    IPC_SET_RETVAL(call->data, 0);
406
    IPC_SET_RETVAL(call->data, 0);
394
    free(call->buffer);
407
    free(call->buffer);
395
    call->buffer = NULL;
408
    call->buffer = NULL;
396
 
409
 
397
    ipc_answer(&TASK->kernel_box, call);
410
    ipc_answer(&TASK->kernel_box, call);
398
}
411
}
399
 
412
 
400
 
413
 
401
/**
414
/**
402
 * Handle a debug call received on the kernel answerbox.
415
 * Handle a debug call received on the kernel answerbox.
403
 *
416
 *
404
 * This is called by the kbox servicing thread.
417
 * This is called by the kbox servicing thread.
405
 */
418
 */
406
void udebug_call_receive(call_t *call)
419
void udebug_call_receive(call_t *call)
407
{
420
{
408
    int debug_method;
421
    int debug_method;
409
 
422
 
410
    debug_method = IPC_GET_ARG1(call->data);
423
    debug_method = IPC_GET_ARG1(call->data);
411
 
424
 
412
    if (debug_method != UDEBUG_M_BEGIN) {
425
    if (debug_method != UDEBUG_M_BEGIN) {
413
        /*
426
        /*
414
         * Verify that the sender is this task's debugger.
427
         * Verify that the sender is this task's debugger.
415
         * Note that this is the only thread that could change
428
         * Note that this is the only thread that could change
416
         * TASK->debugger. Therefore no locking is necessary
429
         * TASK->debugger. Therefore no locking is necessary
417
         * and the sender can be safely considered valid until
430
         * and the sender can be safely considered valid until
418
         * control exits this function.
431
         * control exits this function.
419
         */
432
         */
420
        if (TASK->debugger != call->sender) {
433
        if (TASK->debugger != call->sender) {
421
            IPC_SET_RETVAL(call->data, EINVAL);
434
            IPC_SET_RETVAL(call->data, EINVAL);
422
            ipc_answer(&TASK->kernel_box, call);
435
            ipc_answer(&TASK->kernel_box, call);
423
            return;
436
            return;
424
        }
437
        }
425
    }
438
    }
426
 
439
 
427
    switch (debug_method) {
440
    switch (debug_method) {
428
    case UDEBUG_M_BEGIN:
441
    case UDEBUG_M_BEGIN:
429
        udebug_receive_begin(call);
442
        udebug_receive_begin(call);
430
        break;
443
        break;
431
    case UDEBUG_M_END:
444
    case UDEBUG_M_END:
432
        udebug_receive_end(call);
445
        udebug_receive_end(call);
433
        break;
446
        break;
-
 
447
    case UDEBUG_M_SET_EVMASK:
-
 
448
        udebug_receive_set_evmask(call);
-
 
449
        break;
434
    case UDEBUG_M_GO:
450
    case UDEBUG_M_GO:
435
        udebug_receive_go(call);
451
        udebug_receive_go(call);
436
        break;
452
        break;
437
    case UDEBUG_M_STOP:
453
    case UDEBUG_M_STOP:
438
        udebug_receive_stop(call);
454
        udebug_receive_stop(call);
439
        break;
455
        break;
440
    case UDEBUG_M_THREAD_READ:
456
    case UDEBUG_M_THREAD_READ:
441
        udebug_receive_thread_read(call);
457
        udebug_receive_thread_read(call);
442
        break;
458
        break;
443
    case UDEBUG_M_ARGS_READ:
459
    case UDEBUG_M_ARGS_READ:
444
        udebug_receive_args_read(call);
460
        udebug_receive_args_read(call);
445
        break;
461
        break;
446
    case UDEBUG_M_REGS_READ:
462
    case UDEBUG_M_REGS_READ:
447
        udebug_receive_regs_read(call);
463
        udebug_receive_regs_read(call);
448
        break;
464
        break;
449
    case UDEBUG_M_REGS_WRITE:
465
    case UDEBUG_M_REGS_WRITE:
450
        udebug_receive_regs_write(call);
466
        udebug_receive_regs_write(call);
451
        break;
467
        break;
452
    case UDEBUG_M_MEM_READ:
468
    case UDEBUG_M_MEM_READ:
453
        udebug_receive_mem_read(call);
469
        udebug_receive_mem_read(call);
454
        break;
470
        break;
455
    case UDEBUG_M_MEM_WRITE:
471
    case UDEBUG_M_MEM_WRITE:
456
        udebug_receive_mem_write(call);
472
        udebug_receive_mem_write(call);
457
        break;
473
        break;
458
    }
474
    }
459
}
475
}
460
 
476
 
461
/** @}
477
/** @}
462
 */
478
 */
463
 
479