Subversion Repositories HelenOS

Rev

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

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