Subversion Repositories HelenOS

Rev

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

Rev 3127 Rev 3424
Line 33... Line 33...
33
/**
33
/**
34
 * @file
34
 * @file
35
 * @brief   Udebug operations.
35
 * @brief   Udebug operations.
36
 */
36
 */
37
 
37
 
38
#include <console/klog.h>
38
#include <print.h>
39
#include <proc/task.h>
39
#include <proc/task.h>
40
#include <proc/thread.h>
40
#include <proc/thread.h>
41
#include <arch.h>
41
#include <arch.h>
42
#include <errno.h>
42
#include <errno.h>
43
#include <syscall/copy.h>
43
#include <syscall/copy.h>
Line 160... Line 160...
160
    int reply;
160
    int reply;
161
 
161
 
162
    thread_t *t;
162
    thread_t *t;
163
    link_t *cur;
163
    link_t *cur;
164
 
164
 
165
    klog_printf("udebug_begin()");
165
    printf("udebug_begin()\n");
166
 
166
 
167
    mutex_lock(&TASK->udebug.lock);
167
    mutex_lock(&TASK->udebug.lock);
168
    klog_printf("debugging task %llu", TASK->taskid);
168
    printf("debugging task %llu\n", TASK->taskid);
169
 
169
 
170
    if (TASK->udebug.dt_state != UDEBUG_TS_INACTIVE) {
170
    if (TASK->udebug.dt_state != UDEBUG_TS_INACTIVE) {
171
        mutex_unlock(&TASK->udebug.lock);
171
        mutex_unlock(&TASK->udebug.lock);
172
        klog_printf("udebug_begin(): busy error");
172
        printf("udebug_begin(): busy error\n");
173
 
173
 
174
        return EBUSY;
174
        return EBUSY;
175
    }
175
    }
176
 
176
 
177
    TASK->udebug.dt_state = UDEBUG_TS_BEGINNING;
177
    TASK->udebug.dt_state = UDEBUG_TS_BEGINNING;
Line 197... Line 197...
197
        mutex_unlock(&t->udebug.lock);
197
        mutex_unlock(&t->udebug.lock);
198
    }
198
    }
199
 
199
 
200
    mutex_unlock(&TASK->udebug.lock);
200
    mutex_unlock(&TASK->udebug.lock);
201
 
201
 
202
    klog_printf("udebug_begin() done (%s)",
202
    printf("udebug_begin() done (%s)\n",
203
        reply ? "reply" : "stoppability wait");
203
        reply ? "reply" : "stoppability wait");
204
 
204
 
205
    return reply;
205
    return reply;
206
}
206
}
207
 
207
 
208
int udebug_end(void)
208
int udebug_end(void)
209
{
209
{
210
    int rc;
210
    int rc;
211
 
211
 
212
    klog_printf("udebug_end()");
212
    printf("udebug_end()\n");
213
 
213
 
214
    mutex_lock(&TASK->udebug.lock);
214
    mutex_lock(&TASK->udebug.lock);
215
    klog_printf("task %llu", TASK->taskid);
215
    printf("task %llu\n", TASK->taskid);
216
 
216
 
217
    rc = udebug_task_cleanup(TASK);
217
    rc = udebug_task_cleanup(TASK);
218
 
218
 
219
    mutex_unlock(&TASK->udebug.lock);
219
    mutex_unlock(&TASK->udebug.lock);
220
 
220
 
221
    return rc;
221
    return rc;
222
}
222
}
223
 
223
 
224
int udebug_set_evmask(udebug_evmask_t mask)
224
int udebug_set_evmask(udebug_evmask_t mask)
225
{
225
{
226
    klog_printf("udebug_set_mask()");
226
    printf("udebug_set_mask()\n");
227
 
227
 
228
    klog_printf("debugging task %llu", TASK->taskid);
228
    printf("debugging task %llu\n", TASK->taskid);
229
 
229
 
230
    mutex_lock(&TASK->udebug.lock);
230
    mutex_lock(&TASK->udebug.lock);
231
 
231
 
232
    if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) {
232
    if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) {
233
        mutex_unlock(&TASK->udebug.lock);
233
        mutex_unlock(&TASK->udebug.lock);
234
        klog_printf("udebug_set_mask(): not active debuging session");
234
        printf("udebug_set_mask(): not active debuging session\n");
235
 
235
 
236
        return EINVAL;
236
        return EINVAL;
237
    }
237
    }
238
 
238
 
239
    TASK->udebug.evmask = mask;
239
    TASK->udebug.evmask = mask;
Line 246... Line 246...
246
 
246
 
247
int udebug_go(thread_t *t, call_t *call)
247
int udebug_go(thread_t *t, call_t *call)
248
{
248
{
249
    int rc;
249
    int rc;
250
 
250
 
251
//  klog_printf("udebug_go()");
251
//  printf("udebug_go()\n");
252
 
252
 
253
    /* On success, this will lock t->udebug.lock */
253
    /* On success, this will lock t->udebug.lock */
254
    rc = _thread_op_begin(t, false);
254
    rc = _thread_op_begin(t, false);
255
    if (rc != EOK) {
255
    if (rc != EOK) {
256
        return rc;
256
        return rc;
Line 272... Line 272...
272
 
272
 
273
int udebug_stop(thread_t *t, call_t *call)
273
int udebug_stop(thread_t *t, call_t *call)
274
{
274
{
275
    int rc;
275
    int rc;
276
 
276
 
277
    klog_printf("udebug_stop()");
277
    printf("udebug_stop()\n");
278
    mutex_lock(&TASK->udebug.lock);
278
    mutex_lock(&TASK->udebug.lock);
279
 
279
 
280
    /*
280
    /*
281
     * On success, this will lock t->udebug.lock. Note that this makes sure
281
     * On success, this will lock t->udebug.lock. Note that this makes sure
282
     * the thread is not stopped.
282
     * the thread is not stopped.
Line 296... Line 296...
296
    }
296
    }
297
 
297
 
298
    /*
298
    /*
299
     * Answer GO call
299
     * Answer GO call
300
     */
300
     */
301
    klog_printf("udebug_stop - answering go call");
301
    printf("udebug_stop - answering go call\n");
302
 
302
 
303
    /* Make sure nobody takes this call away from us */
303
    /* Make sure nobody takes this call away from us */
304
    call = t->udebug.go_call;
304
    call = t->udebug.go_call;
305
    t->udebug.go_call = NULL;
305
    t->udebug.go_call = NULL;
306
 
306
 
307
    IPC_SET_RETVAL(call->data, 0);
307
    IPC_SET_RETVAL(call->data, 0);
308
    IPC_SET_ARG1(call->data, UDEBUG_EVENT_STOP);
308
    IPC_SET_ARG1(call->data, UDEBUG_EVENT_STOP);
309
    klog_printf("udebug_stop/ipc_answer");
309
    printf("udebug_stop/ipc_answer\n");
310
 
310
 
311
    THREAD->udebug.cur_event = UDEBUG_EVENT_STOP;
311
    THREAD->udebug.cur_event = UDEBUG_EVENT_STOP;
312
 
312
 
313
    _thread_op_end(t);
313
    _thread_op_end(t);
314
 
314
 
315
    ipc_answer(&TASK->answerbox, call);
315
    ipc_answer(&TASK->answerbox, call);
316
    mutex_unlock(&TASK->udebug.lock);
316
    mutex_unlock(&TASK->udebug.lock);
317
 
317
 
318
    klog_printf("udebog_stop/done");
318
    printf("udebog_stop/done\n");
319
    return 0;
319
    return 0;
320
}
320
}
321
 
321
 
322
int udebug_thread_read(void **buffer, size_t buf_size, size_t *n)
322
int udebug_thread_read(void **buffer, size_t buf_size, size_t *n)
323
{
323
{
Line 328... Line 328...
328
    ipl_t ipl;
328
    ipl_t ipl;
329
    unative_t *id_buffer;
329
    unative_t *id_buffer;
330
    int flags;
330
    int flags;
331
    size_t max_ids;
331
    size_t max_ids;
332
 
332
 
333
    klog_printf("udebug_thread_read()");
333
    printf("udebug_thread_read()\n");
334
 
334
 
335
    /* Allocate a buffer to hold thread IDs */
335
    /* Allocate a buffer to hold thread IDs */
336
    id_buffer = malloc(buf_size, 0);
336
    id_buffer = malloc(buf_size, 0);
337
 
337
 
338
    mutex_lock(&TASK->udebug.lock);
338
    mutex_lock(&TASK->udebug.lock);
Line 383... Line 383...
383
int udebug_args_read(thread_t *t, void **buffer)
383
int udebug_args_read(thread_t *t, void **buffer)
384
{
384
{
385
    int rc;
385
    int rc;
386
    unative_t *arg_buffer;
386
    unative_t *arg_buffer;
387
 
387
 
388
//  klog_printf("udebug_args_read()");
388
//  printf("udebug_args_read()\n");
389
 
389
 
390
    /* Prepare a buffer to hold the arguments */
390
    /* Prepare a buffer to hold the arguments */
391
    arg_buffer = malloc(6 * sizeof(unative_t), 0);
391
    arg_buffer = malloc(6 * sizeof(unative_t), 0);
392
 
392
 
393
    /* On success, this will lock t->udebug.lock */
393
    /* On success, this will lock t->udebug.lock */
Line 415... Line 415...
415
int udebug_regs_read(thread_t *t, void *buffer)
415
int udebug_regs_read(thread_t *t, void *buffer)
416
{
416
{
417
    istate_t *state;
417
    istate_t *state;
418
    int rc;
418
    int rc;
419
 
419
 
420
//  klog_printf("udebug_regs_read()");
420
//  printf("udebug_regs_read()\n");
421
 
421
 
422
    /* On success, this will lock t->udebug.lock */
422
    /* On success, this will lock t->udebug.lock */
423
    rc = _thread_op_begin(t, false);
423
    rc = _thread_op_begin(t, false);
424
    if (rc != EOK) {
424
    if (rc != EOK) {
425
        return rc;
425
        return rc;
426
    }
426
    }
427
 
427
 
428
    state = t->udebug.uspace_state;
428
    state = t->udebug.uspace_state;
429
    if (state == NULL) {
429
    if (state == NULL) {
430
        _thread_op_end(t);
430
        _thread_op_end(t);
431
        klog_printf("udebug_regs_read() - istate not available");
431
        printf("udebug_regs_read() - istate not available\n");
432
        return EBUSY;
432
        return EBUSY;
433
    }
433
    }
434
 
434
 
435
    /* Copy to the allocated buffer */
435
    /* Copy to the allocated buffer */
436
    memcpy(buffer, state, sizeof(istate_t));
436
    memcpy(buffer, state, sizeof(istate_t));
Line 443... Line 443...
443
int udebug_regs_write(thread_t *t, void *buffer)
443
int udebug_regs_write(thread_t *t, void *buffer)
444
{
444
{
445
    int rc;
445
    int rc;
446
    istate_t *state;
446
    istate_t *state;
447
 
447
 
448
    klog_printf("udebug_regs_write()");
448
    printf("udebug_regs_write()\n");
449
 
449
 
450
    /* Try to change the thread's uspace_state */
450
    /* Try to change the thread's uspace_state */
451
 
451
 
452
    /* On success, this will lock t->udebug.lock */
452
    /* On success, this will lock t->udebug.lock */
453
    rc = _thread_op_begin(t, false);
453
    rc = _thread_op_begin(t, false);
454
    if (rc != EOK) {
454
    if (rc != EOK) {
455
        klog_printf("error locking thread");
455
        printf("error locking thread\n");
456
        return rc;
456
        return rc;
457
    }
457
    }
458
 
458
 
459
    state = t->udebug.uspace_state;
459
    state = t->udebug.uspace_state;
460
    if (state == NULL) {
460
    if (state == NULL) {
461
        _thread_op_end(t);
461
        _thread_op_end(t);
462
        klog_printf("udebug_regs_write() - istate not available");
462
        printf("udebug_regs_write() - istate not available\n");
463
        return EBUSY;
463
        return EBUSY;
464
    }
464
    }
465
 
465
 
466
    memcpy(t->udebug.uspace_state, buffer, sizeof(istate_t));
466
    memcpy(t->udebug.uspace_state, buffer, sizeof(istate_t));
467
 
467
 
Line 484... Line 484...
484
        return EBUSY;
484
        return EBUSY;
485
    }
485
    }
486
 
486
 
487
    data_buffer = malloc(n, 0);
487
    data_buffer = malloc(n, 0);
488
 
488
 
489
//  klog_printf("udebug_mem_read: src=%u, size=%u", uspace_addr, n);
489
//  printf("udebug_mem_read: src=%u, size=%u\n", uspace_addr, n);
490
 
490
 
491
    /* NOTE: this is not strictly from a syscall... but that shouldn't
491
    /* NOTE: this is not strictly from a syscall... but that shouldn't
492
     * be a problem */
492
     * be a problem */
493
    rc = copy_from_uspace(data_buffer, (void *)uspace_addr, n);
493
    rc = copy_from_uspace(data_buffer, (void *)uspace_addr, n);
494
    mutex_unlock(&TASK->udebug.lock);
494
    mutex_unlock(&TASK->udebug.lock);
Line 501... Line 501...
501
 
501
 
502
int udebug_mem_write(unative_t uspace_addr, void *data, size_t n)
502
int udebug_mem_write(unative_t uspace_addr, void *data, size_t n)
503
{
503
{
504
    int rc;
504
    int rc;
505
 
505
 
506
    klog_printf("udebug_mem_write()");
506
    printf("udebug_mem_write()\n");
507
 
507
 
508
    /* n must be positive */
508
    /* n must be positive */
509
    if (n < 1)
509
    if (n < 1)
510
        return EINVAL;
510
        return EINVAL;
511
 
511
 
Line 515... Line 515...
515
    if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) {
515
    if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) {
516
        mutex_unlock(&TASK->udebug.lock);
516
        mutex_unlock(&TASK->udebug.lock);
517
        return EBUSY;
517
        return EBUSY;
518
    }
518
    }
519
   
519
   
520
    klog_printf("dst=%u, size=%u", uspace_addr, n);
520
    printf("dst=%u, size=%u\n", uspace_addr, n);
521
 
521
 
522
    /* NOTE: this is not strictly from a syscall... but that shouldn't
522
    /* NOTE: this is not strictly from a syscall... but that shouldn't
523
     * be a problem */
523
     * be a problem */
524
//  rc = copy_to_uspace((void *)uspace_addr, data, n);
524
//  rc = copy_to_uspace((void *)uspace_addr, data, n);
525
//  if (rc) return rc;
525
//  if (rc) return rc;
526
 
526
 
527
    rc = as_debug_write(uspace_addr, data, n);
527
    rc = as_debug_write(uspace_addr, data, n);
528
   
528
   
529
    klog_printf("rc=%d\n", rc);
529
    printf("rc=%d\n", rc);
530
 
530
 
531
    mutex_unlock(&TASK->udebug.lock);
531
    mutex_unlock(&TASK->udebug.lock);
532
 
532
 
533
    return rc;
533
    return rc;
534
}
534
}