Subversion Repositories HelenOS

Rev

Rev 2885 | Rev 2887 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2885 Rev 2886
Line 16... Line 16...
16
#include <syscall/copy.h>
16
#include <syscall/copy.h>
17
#include <udebug/udebug.h>
17
#include <udebug/udebug.h>
18
#include <udebug/udebug_ipc.h>
18
#include <udebug/udebug_ipc.h>
19
 
19
 
20
/**
20
/**
21
 * Get a phone's callee task id.
-
 
22
 *
-
 
23
 * This will return the id of the task to which the phone
-
 
24
 * is connected.
-
 
25
 *
-
 
26
 * Interrupts must be already disabled.
-
 
27
 */
-
 
28
static task_id_t get_callee_task_id(phone_t *phone)
-
 
29
{
-
 
30
    answerbox_t *box;
-
 
31
    task_id_t taskid;
-
 
32
 
-
 
33
    spinlock_lock(&phone->lock);
-
 
34
    if (phone->state != IPC_PHONE_CONNECTED) {
-
 
35
        spinlock_unlock(&phone->lock);
-
 
36
        return NULL;
-
 
37
    }
-
 
38
 
-
 
39
    box = phone->callee;
-
 
40
   
-
 
41
    spinlock_lock(&box->lock);
-
 
42
    taskid = box->task->taskid;
-
 
43
    spinlock_unlock(&box->lock);
-
 
44
    spinlock_unlock(&phone->lock);
-
 
45
 
-
 
46
    return taskid;
-
 
47
}
-
 
48
 
-
 
49
/**
-
 
50
 * Prepare a thread for a debugging operation.
21
 * Prepare a thread for a debugging operation.
51
 *
22
 *
52
 * Simply put, return thread t with t->debug_lock held,
23
 * Simply put, return thread t with t->debug_lock held,
53
 * but only if it verifies all conditions.
24
 * but only if it verifies all conditions.
54
 *
25
 *
55
 * Specifically, verifies that thread t exists, is a userspace thread,
26
 * Specifically, verifies that thread t exists, is a userspace thread,
56
 * belongs to the callee of 'phone'. It also locks t->debug_lock,
27
 * and belongs to the current task (TASK). It also locks t->debug_lock,
57
 * making sure that t->debug_active is true - that the thread is
28
 * making sure that t->debug_active is true - that the thread is
58
 * in a valid debugging session.
29
 * in a valid debugging session.
59
 *
30
 *
60
 * Returns EOK if all went well, or an error code otherwise.
31
 * Returns EOK if all went well, or an error code otherwise.
61
 * Interrupts must be already disabled when calling this function.
32
 * Interrupts must be already disabled when calling this function.
62
 *
33
 *
63
 * Note: This function sports complicated locking.
34
 * Note: This function sports complicated locking.
64
 */
35
 */
65
static int _thread_op_begin(phone_t *phone, thread_t *t)
36
static int _thread_op_begin(thread_t *t)
66
{
37
{
67
    int rc;
38
    int rc;
68
    task_id_t taskid;
39
    task_id_t taskid;
69
    int task_match;
-
 
70
    DEADLOCK_PROBE_INIT(p_tasklock);
-
 
71
 
40
 
72
    taskid = get_callee_task_id(phone);
41
    taskid = TASK->taskid;
73
 
42
 
74
    /* Need to lock down the thread and than it's owner task */
43
    /* Must lock threads_lock to ensure continued existence of the thread */
75
grab_locks:
-
 
76
    spinlock_lock(&threads_lock);
44
    spinlock_lock(&threads_lock);
77
 
45
 
78
    if (!thread_exists(t)) {
46
    if (!thread_exists(t)) {
79
        spinlock_unlock(&threads_lock);
47
        spinlock_unlock(&threads_lock);
80
        return ENOENT;
48
        return ENOENT;
81
    }
49
    }
82
 
50
 
83
    spinlock_lock(&t->debug_lock);
51
    spinlock_lock(&t->debug_lock);
84
    spinlock_lock(&t->lock);
52
    spinlock_lock(&t->lock);
85
   
53
   
86
    if (!spinlock_trylock(&t->task->lock)) {
-
 
87
        spinlock_unlock(&t->lock);
-
 
88
        spinlock_unlock(&t->debug_lock);
-
 
89
        DEADLOCK_PROBE(p_tasklock, DEADLOCK_THRESHOLD);
-
 
90
        goto grab_locks;    /* avoid deadlock */
-
 
91
    }
-
 
92
 
-
 
93
    /* Now verify that it's the callee */
54
    /* Now verify that it's the current task */
94
    task_match = (t->task->taskid == taskid);
-
 
95
 
-
 
96
    spinlock_unlock(&t->task->lock);
-
 
97
 
-
 
98
    if (!task_match) {
55
    if (t->task != TASK) {
99
        /* No such thread belonging to callee */
56
        /* No such thread belonging to callee */
100
        rc = ENOENT;
57
        rc = ENOENT;
101
        goto error_exit;
58
        goto error_exit;
102
    }
59
    }
103
 
60
 
Line 130... Line 87...
130
 
87
 
131
    /* No locks left here */
88
    /* No locks left here */
132
    return rc;  /* Some errors occured */
89
    return rc;  /* Some errors occured */
133
}
90
}
134
 
91
 
-
 
92
 
135
static void _thread_op_end(thread_t *t)
93
static void _thread_op_end(thread_t *t)
136
{
94
{
137
    spinlock_unlock(&t->debug_lock);
95
    spinlock_unlock(&t->debug_lock);
138
}
96
}
139
 
97
 
140
static int udebug_rp_go(call_t *call, phone_t *phone)
-
 
141
{
-
 
142
    thread_t *t;
-
 
143
    ipl_t ipl;
-
 
144
    int rc;
-
 
145
 
-
 
146
    klog_printf("debug_go()");
-
 
147
 
-
 
148
    t = (thread_t *)IPC_GET_ARG2(call->data);
-
 
149
 
-
 
150
    ipl = interrupts_disable();
-
 
151
 
-
 
152
    /* On success, this will lock t->debug_lock */
-
 
153
    rc = _thread_op_begin(phone, t);
-
 
154
    if (rc != EOK) {
-
 
155
        interrupts_restore(ipl);
-
 
156
        return rc;
-
 
157
    }
-
 
158
 
-
 
159
    t->debug_go_call = call;
-
 
160
    t->debug_stop = false;
-
 
161
    t->cur_event = 0;   /* none */
-
 
162
 
-
 
163
    /*
-
 
164
     * Neither t's lock nor threads_lock may be held during wakeup
-
 
165
     */
-
 
166
    waitq_wakeup(&t->go_wq, WAKEUP_FIRST);
-
 
167
 
-
 
168
    _thread_op_end(t);
-
 
169
    interrupts_restore(ipl);
-
 
170
 
-
 
171
    return 0; /* no backsend */
-
 
172
}
-
 
173
 
-
 
174
static int udebug_rp_args_read(call_t *call, phone_t *phone)
-
 
175
{
-
 
176
    thread_t *t;
-
 
177
    void *uspace_buffer;
-
 
178
    int rc;
-
 
179
    ipl_t ipl;
-
 
180
    unative_t buffer[6];
-
 
181
 
-
 
182
    klog_printf("debug_args_read()");
-
 
183
 
-
 
184
    t = (thread_t *)IPC_GET_ARG2(call->data);
-
 
185
 
-
 
186
    ipl = interrupts_disable();
-
 
187
 
-
 
188
    /* On success, this will lock t->debug_lock */
-
 
189
    rc = _thread_op_begin(phone, t);
-
 
190
    if (rc != EOK) {
-
 
191
        interrupts_restore(ipl);
-
 
192
        return rc;
-
 
193
    }
-
 
194
 
-
 
195
    /* Additionally we need to verify that we are inside a syscall */
-
 
196
    if (t->cur_event != UDEBUG_EVENT_SYSCALL) {
-
 
197
        _thread_op_end(t);
-
 
198
        interrupts_restore(ipl);
-
 
199
        return EINVAL;
-
 
200
    }
-
 
201
 
-
 
202
    /* Copy to a local buffer before releasing the lock */
-
 
203
    memcpy(buffer, t->syscall_args, 6 * sizeof(unative_t));
-
 
204
 
-
 
205
    _thread_op_end(t);
-
 
206
    interrupts_restore(ipl);
-
 
207
 
-
 
208
    /* Now copy to userspace */
-
 
209
 
-
 
210
    uspace_buffer = (void *)IPC_GET_ARG3(call->data);
-
 
211
 
-
 
212
    rc = copy_to_uspace(uspace_buffer, buffer, 6 * sizeof(unative_t));
-
 
213
    if (rc != 0) {
-
 
214
        klog_printf("debug_args_read() - copy failed");
-
 
215
        return rc;
-
 
216
    }
-
 
217
 
-
 
218
    klog_printf("debug_args_read() done");
-
 
219
    return 1; /* actually need becksend with retval 0 */
-
 
220
}
-
 
221
 
-
 
222
static int udebug_rp_regs_read(call_t *call, phone_t *phone)
-
 
223
{
-
 
224
    thread_t *t;
-
 
225
    void *uspace_buffer;
-
 
226
    unative_t to_copy;
-
 
227
    int rc;
-
 
228
    istate_t *state;
-
 
229
    istate_t state_copy;
-
 
230
    ipl_t ipl;
-
 
231
 
-
 
232
    klog_printf("debug_regs_read()");
-
 
233
 
-
 
234
    t = (thread_t *) IPC_GET_ARG2(call->data);
-
 
235
 
-
 
236
    ipl = interrupts_disable();
-
 
237
 
-
 
238
    /* On success, this will lock t->debug_lock */
-
 
239
    rc = _thread_op_begin(phone, t);
-
 
240
    if (rc != EOK) {
-
 
241
        interrupts_restore(ipl);
-
 
242
        return rc;
-
 
243
    }
-
 
244
 
-
 
245
    state = t->uspace_state;
-
 
246
    if (state == NULL) {
-
 
247
        _thread_op_end(t);
-
 
248
        interrupts_restore(ipl);
-
 
249
        klog_printf("debug_regs_read() - istate not available");
-
 
250
        return EBUSY;
-
 
251
    }
-
 
252
 
-
 
253
    /* Copy to a local buffer so that we can release the lock */
-
 
254
    memcpy(&state_copy, state, sizeof(state_copy));
-
 
255
    _thread_op_end(t);
-
 
256
    interrupts_restore(ipl);
-
 
257
 
-
 
258
    uspace_buffer = (void *)IPC_GET_ARG3(call->data);
-
 
259
    to_copy = IPC_GET_ARG4(call->data);
-
 
260
    if (to_copy > sizeof(istate_t)) to_copy = sizeof(istate_t);
-
 
261
 
-
 
262
    rc = copy_to_uspace(uspace_buffer, &state_copy, to_copy);
-
 
263
    if (rc != 0) {
-
 
264
        klog_printf("debug_regs_read() - copy failed");
-
 
265
        return rc;
-
 
266
    }
-
 
267
 
-
 
268
    IPC_SET_ARG1(call->data, to_copy);
-
 
269
    IPC_SET_ARG2(call->data, sizeof(istate_t));
-
 
270
 
-
 
271
    klog_printf("debug_regs_read() done");
-
 
272
    return 1; /* actually need becksend with retval 0 */
-
 
273
}
-
 
274
 
-
 
275
 
-
 
276
 
-
 
277
static int udebug_rp_regs_write(call_t *call, phone_t *phone)
98
static int udebug_rp_regs_write(call_t *call, phone_t *phone)
278
{
99
{
279
    thread_t *t;
-
 
280
    void *uspace_data;
100
    void *uspace_data;
281
    unative_t to_copy;
101
    unative_t to_copy;
282
    int rc;
102
    int rc;
283
    istate_t *state;
103
    void *buffer;
284
    istate_t data_copy;
-
 
285
    ipl_t ipl;
-
 
286
 
104
 
287
    klog_printf("debug_regs_write()");
105
    klog_printf("debug_regs_write()");
288
 
106
 
289
    /* First copy to a local buffer */
-
 
290
 
-
 
291
    uspace_data = (void *)IPC_GET_ARG3(call->data);
107
    uspace_data = (void *)IPC_GET_ARG3(call->data);
292
    to_copy = IPC_GET_ARG4(call->data);
108
    to_copy = IPC_GET_ARG4(call->data);
293
    if (to_copy > sizeof(istate_t)) to_copy = sizeof(istate_t);
109
    if (to_copy > sizeof(istate_t)) to_copy = sizeof(istate_t);
294
 
110
 
-
 
111
    buffer = malloc(to_copy, 0); // ??? 
-
 
112
 
295
    rc = copy_from_uspace(&data_copy, uspace_data, to_copy);
113
    rc = copy_from_uspace(buffer, uspace_data, to_copy);
296
    if (rc != 0) {
114
    if (rc != 0) {
297
        klog_printf("debug_regs_write() - copy failed");
115
        klog_printf("debug_regs_write() - copy failed");
298
        return rc;
116
        return rc;
299
    }
117
    }
300
 
118
 
301
    /* Now try to change the thread's uspace_state */
-
 
302
 
-
 
303
    ipl = interrupts_disable();
-
 
304
    t = (thread_t *) IPC_GET_ARG2(call->data);
-
 
305
 
-
 
306
    /* On success, this will lock t->debug_lock */
-
 
307
    rc = _thread_op_begin(phone, t);
-
 
308
    if (rc != EOK) {
-
 
309
        interrupts_restore(ipl);
-
 
310
        return rc;
-
 
311
    }
-
 
312
 
-
 
313
    state = t->uspace_state;
-
 
314
    if (state == NULL) {
-
 
315
        _thread_op_end(t);
-
 
316
        interrupts_restore(ipl);
-
 
317
        klog_printf("debug_regs_write() - istate not available");
-
 
318
        return EBUSY;
-
 
319
    }
-
 
320
 
-
 
321
    memcpy(t->uspace_state, &data_copy, sizeof(t->uspace_state));
-
 
322
 
-
 
323
    _thread_op_end(t);
-
 
324
    interrupts_restore(ipl);
-
 
325
 
-
 
326
    /* Set answer values */
119
    call->buffer = buffer;
327
 
-
 
328
    IPC_SET_ARG1(call->data, to_copy);
-
 
329
    IPC_SET_ARG2(call->data, sizeof(istate_t));
-
 
330
 
120
 
331
    klog_printf("debug_regs_write() done");
121
    klog_printf(" - done");
332
    return 1; /* actually need becksend with retval 0 */
122
    return 0; /* No backsend */
333
}
123
}
334
 
124
 
335
static int udebug_rp_mem_write(call_t *call, phone_t *phone)
125
static int udebug_rp_mem_write(call_t *call, phone_t *phone)
336
{
126
{
337
    void *uspace_data;
127
    void *uspace_data;
Line 362... Line 152...
362
int udebug_request_preprocess(call_t *call, phone_t *phone)
152
int udebug_request_preprocess(call_t *call, phone_t *phone)
363
{
153
{
364
    int rc;
154
    int rc;
365
 
155
 
366
    switch (IPC_GET_ARG1(call->data)) {
156
    switch (IPC_GET_ARG1(call->data)) {
367
    case UDEBUG_M_GO:
-
 
368
        rc = udebug_rp_go(call, phone);
-
 
369
        return rc;
-
 
370
    case UDEBUG_M_ARGS_READ:
-
 
371
        rc = udebug_rp_args_read(call, phone);
-
 
372
        return rc;
-
 
373
    case UDEBUG_M_REGS_READ:
-
 
374
        rc = udebug_rp_regs_read(call, phone);
-
 
375
        return rc;
-
 
376
    case UDEBUG_M_REGS_WRITE:
157
    case UDEBUG_M_REGS_WRITE:
377
        rc = udebug_rp_regs_write(call, phone);
158
        rc = udebug_rp_regs_write(call, phone);
378
        return rc;
159
        return rc;
379
    case UDEBUG_M_MEM_WRITE:
160
    case UDEBUG_M_MEM_WRITE:
380
        rc = udebug_rp_mem_write(call, phone);
161
        rc = udebug_rp_mem_write(call, phone);
Line 467... Line 248...
467
 
248
 
468
    IPC_SET_RETVAL(call->data, 0);
249
    IPC_SET_RETVAL(call->data, 0);
469
    ipc_answer(&TASK->kernel_box, call);
250
    ipc_answer(&TASK->kernel_box, call);
470
}
251
}
471
 
252
 
-
 
253
static void udebug_receive_go(call_t *call)
-
 
254
{
-
 
255
    thread_t *t;
-
 
256
    ipl_t ipl;
-
 
257
    int rc;
-
 
258
 
-
 
259
    klog_printf("debug_go()");
-
 
260
 
-
 
261
    t = (thread_t *)IPC_GET_ARG2(call->data);
-
 
262
 
-
 
263
    ipl = interrupts_disable();
-
 
264
 
-
 
265
    /* On success, this will lock t->debug_lock */
-
 
266
    rc = _thread_op_begin(t);
-
 
267
    if (rc != EOK) {
-
 
268
        interrupts_restore(ipl);
-
 
269
 
-
 
270
        IPC_SET_RETVAL(call->data, rc);
-
 
271
        ipc_answer(&TASK->kernel_box, call);
-
 
272
        return;
-
 
273
    }
-
 
274
 
-
 
275
    t->debug_go_call = call;
-
 
276
    t->debug_stop = false;
-
 
277
    t->cur_event = 0;   /* none */
-
 
278
 
-
 
279
    /*
-
 
280
     * Neither t's lock nor threads_lock may be held during wakeup
-
 
281
     */
-
 
282
    waitq_wakeup(&t->go_wq, WAKEUP_FIRST);
-
 
283
 
-
 
284
    _thread_op_end(t);
-
 
285
    interrupts_restore(ipl);
-
 
286
 
-
 
287
    /* No reply */
-
 
288
}
-
 
289
 
-
 
290
 
472
static void udebug_receive_thread_read(call_t *call)
291
static void udebug_receive_thread_read(call_t *call)
473
{
292
{
474
    thread_t *t;
293
    thread_t *t;
475
    link_t *cur;
294
    link_t *cur;
476
    unative_t uspace_addr;
295
    unative_t uspace_addr;
Line 553... Line 372...
553
    call->buffer = (void *)buffer;
372
    call->buffer = (void *)buffer;
554
 
373
 
555
    ipc_answer(&TASK->kernel_box, call);
374
    ipc_answer(&TASK->kernel_box, call);
556
}
375
}
557
 
376
 
-
 
377
static void udebug_receive_args_read(call_t *call)
-
 
378
{
-
 
379
    thread_t *t;
-
 
380
    unative_t uspace_addr;
-
 
381
    int rc;
-
 
382
    ipl_t ipl;
-
 
383
    unative_t *buffer;
-
 
384
 
-
 
385
    klog_printf("debug_args_read()");
-
 
386
 
-
 
387
    t = (thread_t *)IPC_GET_ARG2(call->data);
-
 
388
 
-
 
389
    ipl = interrupts_disable();
-
 
390
 
-
 
391
    /* On success, this will lock t->debug_lock */
-
 
392
    rc = _thread_op_begin(t);
-
 
393
    if (rc != EOK) {
-
 
394
        interrupts_restore(ipl);
-
 
395
        IPC_SET_RETVAL(call->data, rc);
-
 
396
        ipc_answer(&TASK->kernel_box, call);
-
 
397
        return;
-
 
398
    }
-
 
399
 
-
 
400
    /* Additionally we need to verify that we are inside a syscall */
-
 
401
    if (t->cur_event != UDEBUG_EVENT_SYSCALL) {
-
 
402
        _thread_op_end(t);
-
 
403
        interrupts_restore(ipl);
-
 
404
 
-
 
405
        IPC_SET_RETVAL(call->data, EINVAL);
-
 
406
        ipc_answer(&TASK->kernel_box, call);
-
 
407
        return;
-
 
408
    }
-
 
409
 
-
 
410
    /* Copy to a local buffer before releasing the lock */
-
 
411
    buffer = malloc(6 * sizeof(unative_t), 0); // ???
-
 
412
    memcpy(buffer, t->syscall_args, 6 * sizeof(unative_t));
-
 
413
 
-
 
414
    _thread_op_end(t);
-
 
415
    interrupts_restore(ipl);
-
 
416
 
-
 
417
    /*
-
 
418
     * Make use of call->buffer to transfer data to caller's userspace
-
 
419
     */
-
 
420
 
-
 
421
    uspace_addr = IPC_GET_ARG3(call->data);
-
 
422
 
-
 
423
    IPC_SET_RETVAL(call->data, 0);
-
 
424
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
-
 
425
       same code in process_answer() can be used
-
 
426
       (no way to distinguish method in answer) */
-
 
427
    IPC_SET_ARG1(call->data, uspace_addr);
-
 
428
    IPC_SET_ARG2(call->data, 6 * sizeof(unative_t));
-
 
429
    call->buffer = (void *)buffer;
-
 
430
 
-
 
431
    ipc_answer(&TASK->kernel_box, call);
-
 
432
}
-
 
433
 
-
 
434
static void udebug_receive_regs_read(call_t *call)
-
 
435
{
-
 
436
    thread_t *t;
-
 
437
    unative_t uspace_addr;
-
 
438
    unative_t to_copy;
-
 
439
    unative_t buf_size;
-
 
440
    unative_t total_bytes;
-
 
441
    istate_t *state;
-
 
442
    void *buffer;
-
 
443
    int rc;
-
 
444
    ipl_t ipl;
-
 
445
 
-
 
446
    klog_printf("debug_regs_read()");
-
 
447
 
-
 
448
    t = (thread_t *) IPC_GET_ARG2(call->data);
-
 
449
 
-
 
450
    ipl = interrupts_disable();
-
 
451
 
-
 
452
    /* On success, this will lock t->debug_lock */
-
 
453
    rc = _thread_op_begin(t);
-
 
454
    if (rc != EOK) {
-
 
455
        interrupts_restore(ipl);
-
 
456
 
-
 
457
        IPC_SET_RETVAL(call->data, rc);
-
 
458
        ipc_answer(&TASK->kernel_box, call);
-
 
459
        return;
-
 
460
    }
-
 
461
 
-
 
462
    state = t->uspace_state;
-
 
463
    if (state == NULL) {
-
 
464
        _thread_op_end(t);
-
 
465
        interrupts_restore(ipl);
-
 
466
        klog_printf("debug_regs_read() - istate not available");
-
 
467
 
-
 
468
        IPC_SET_RETVAL(call->data, EBUSY);
-
 
469
        ipc_answer(&TASK->kernel_box, call);
-
 
470
        return;
-
 
471
    }
-
 
472
 
-
 
473
    /* Copy to an allocated buffer */
-
 
474
    buffer = malloc(sizeof(istate_t), 0); // ???
-
 
475
    memcpy(buffer, state, sizeof(istate_t));
-
 
476
 
-
 
477
    _thread_op_end(t);
-
 
478
    interrupts_restore(ipl);
-
 
479
 
-
 
480
    /*
-
 
481
     * Make use of call->buffer to transfer data to caller's userspace
-
 
482
     */
-
 
483
 
-
 
484
    uspace_addr = IPC_GET_ARG3(call->data);
-
 
485
    buf_size = IPC_GET_ARG4(call->data);
-
 
486
 
-
 
487
    total_bytes = sizeof(istate_t);
-
 
488
 
-
 
489
    if (buf_size > total_bytes)
-
 
490
        to_copy = total_bytes;
-
 
491
    else
-
 
492
        to_copy = buf_size;
-
 
493
 
-
 
494
    IPC_SET_RETVAL(call->data, 0);
-
 
495
    /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
-
 
496
       same code in process_answer() can be used
-
 
497
       (no way to distinguish method in answer) */
-
 
498
    IPC_SET_ARG1(call->data, uspace_addr);
-
 
499
    IPC_SET_ARG2(call->data, to_copy);
-
 
500
 
-
 
501
    IPC_SET_ARG3(call->data, total_bytes);
-
 
502
    call->buffer = (void *)buffer;
-
 
503
 
-
 
504
    ipc_answer(&TASK->kernel_box, call);
-
 
505
}
-
 
506
 
-
 
507
static void udebug_receive_regs_write(call_t *call)
-
 
508
{
-
 
509
    thread_t *t;
-
 
510
    void *uspace_data;
-
 
511
    unative_t to_copy;
-
 
512
    int rc;
-
 
513
    istate_t *state;
-
 
514
    ipl_t ipl;
-
 
515
 
-
 
516
    klog_printf("debug_regs_write()");
-
 
517
 
-
 
518
    uspace_data = (void *)IPC_GET_ARG3(call->data);
-
 
519
    to_copy = IPC_GET_ARG4(call->data);
-
 
520
 
-
 
521
    /* Try to change the thread's uspace_state */
-
 
522
 
-
 
523
    ipl = interrupts_disable();
-
 
524
    t = (thread_t *) IPC_GET_ARG2(call->data);
-
 
525
 
-
 
526
    /* On success, this will lock t->debug_lock */
-
 
527
    rc = _thread_op_begin(t);
-
 
528
    if (rc != EOK) {
-
 
529
        interrupts_restore(ipl);
-
 
530
 
-
 
531
        IPC_SET_RETVAL(call->data, rc);
-
 
532
        ipc_answer(&TASK->kernel_box, call);
-
 
533
        return;
-
 
534
    }
-
 
535
 
-
 
536
    state = t->uspace_state;
-
 
537
    if (state == NULL) {
-
 
538
        _thread_op_end(t);
-
 
539
        interrupts_restore(ipl);
-
 
540
        klog_printf("debug_regs_write() - istate not available");
-
 
541
 
-
 
542
        IPC_SET_RETVAL(call->data, EBUSY);
-
 
543
        ipc_answer(&TASK->kernel_box, call);
-
 
544
        return;
-
 
545
    }
-
 
546
 
-
 
547
    memcpy(t->uspace_state, call->buffer, sizeof(t->uspace_state));
-
 
548
 
-
 
549
    _thread_op_end(t);
-
 
550
    interrupts_restore(ipl);
-
 
551
 
-
 
552
    /* Set answer values */
-
 
553
 
-
 
554
    IPC_SET_ARG1(call->data, to_copy);
-
 
555
    IPC_SET_ARG2(call->data, sizeof(istate_t));
-
 
556
 
-
 
557
    IPC_SET_RETVAL(call->data, 0);
-
 
558
    ipc_answer(&TASK->kernel_box, call);
-
 
559
 
-
 
560
    klog_printf("debug_regs_write() done");
-
 
561
}
-
 
562
 
558
 
563
 
559
static void udebug_receive_mem_read(call_t *call)
564
static void udebug_receive_mem_read(call_t *call)
560
{
565
{
561
    unative_t uspace_dst;
566
    unative_t uspace_dst;
562
    void *uspace_ptr;
567
    void *uspace_ptr;
Line 575... Line 580...
575
    /* NOTE: this is not strictly from a syscall... but that shouldn't
580
    /* NOTE: this is not strictly from a syscall... but that shouldn't
576
     * be a problem */
581
     * be a problem */
577
    rc = copy_from_uspace(buffer, uspace_ptr, size);
582
    rc = copy_from_uspace(buffer, uspace_ptr, size);
578
    if (rc) {
583
    if (rc) {
579
        IPC_SET_RETVAL(call->data, rc);
584
        IPC_SET_RETVAL(call->data, rc);
-
 
585
        ipc_answer(&TASK->kernel_box, call);
580
        return;
586
        return;
581
    }
587
    }
582
 
588
 
583
    klog_printf("first word: %u", *((unative_t *)buffer));
589
    klog_printf("first word: %u", *((unative_t *)buffer));
584
 
590
 
Line 654... Line 660...
654
        udebug_receive_begin(call);
660
        udebug_receive_begin(call);
655
        break;
661
        break;
656
    case UDEBUG_M_END:
662
    case UDEBUG_M_END:
657
        udebug_receive_end(call);
663
        udebug_receive_end(call);
658
        break;
664
        break;
-
 
665
    case UDEBUG_M_GO:
-
 
666
        udebug_receive_go(call);
-
 
667
        break;
659
    case UDEBUG_M_THREAD_READ:
668
    case UDEBUG_M_THREAD_READ:
660
        udebug_receive_thread_read(call);
669
        udebug_receive_thread_read(call);
661
        break;
670
        break;
-
 
671
    case UDEBUG_M_ARGS_READ:
-
 
672
        udebug_receive_args_read(call);
-
 
673
        break;
-
 
674
    case UDEBUG_M_REGS_READ:
-
 
675
        udebug_receive_regs_read(call);
-
 
676
        break;
-
 
677
    case UDEBUG_M_REGS_WRITE:
-
 
678
        udebug_receive_regs_write(call);
-
 
679
        break;
662
    case UDEBUG_M_MEM_READ:
680
    case UDEBUG_M_MEM_READ:
663
        udebug_receive_mem_read(call);
681
        udebug_receive_mem_read(call);
664
        break;
682
        break;
665
    case UDEBUG_M_MEM_WRITE:
683
    case UDEBUG_M_MEM_WRITE:
666
        udebug_receive_mem_write(call);
684
        udebug_receive_mem_write(call);