Subversion Repositories HelenOS

Rev

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

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