Subversion Repositories HelenOS

Rev

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

Rev 2826 Rev 2827
Line 67... Line 67...
67
 
67
 
68
static int udebug_rp_begin(call_t *call, phone_t *phone)
68
static int udebug_rp_begin(call_t *call, phone_t *phone)
69
{
69
{
70
    task_t *ta;
70
    task_t *ta;
71
    ipl_t ipl;
71
    ipl_t ipl;
-
 
72
    int rc;
-
 
73
 
-
 
74
    thread_t *t;
-
 
75
    link_t *cur;
72
 
76
 
73
    klog_printf("debug_begin()");
77
    klog_printf("debug_begin()");
74
 
78
 
75
    ipl = interrupts_disable();
79
    ipl = interrupts_disable();
76
    ta = get_lock_callee_task(phone);
80
    ta = get_lock_callee_task(phone);
Line 87... Line 91...
87
    ta->debug_begin_call = call;
91
    ta->debug_begin_call = call;
88
 
92
 
89
    if (ta->not_stoppable_count == 0) {
93
    if (ta->not_stoppable_count == 0) {
90
        ta->dt_state = UDEBUG_TS_ACTIVE;
94
        ta->dt_state = UDEBUG_TS_ACTIVE;
91
        ta->debug_begin_call = NULL;
95
        ta->debug_begin_call = NULL;
-
 
96
        rc = 1; /* actually we need backsend with 0 retval */
-
 
97
    } else {
-
 
98
        rc = 0; /* no backsend */
-
 
99
    }
-
 
100
   
-
 
101
    /* Set debug_active on all of the task's userspace threads */
-
 
102
 
-
 
103
    for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
-
 
104
        t = list_get_instance(cur, thread_t, th_link);
-
 
105
 
92
        spinlock_unlock(&ta->lock);
106
        spinlock_lock(&t->lock);
93
        interrupts_restore(ipl);
107
        if ((t->flags & THREAD_FLAG_USPACE) != 0)
94
        klog_printf("debug_begin(): immediate backsend");
108
            t->debug_active = true;
95
        return 1; /* actually we need backsend with 0 retval */
109
        spinlock_unlock(&t->lock);
96
    }
110
    }
97
 
111
 
98
    spinlock_unlock(&ta->lock);
112
    spinlock_unlock(&ta->lock);
99
    interrupts_restore(ipl);
113
    interrupts_restore(ipl);
100
 
114
 
101
    klog_printf("debug_begin() done (wait for stoppability)");
115
    klog_printf("debug_begin() done (%s)",
-
 
116
        rc ? "backsend" : "stoppability wait");
-
 
117
 
102
    return 0;
118
    return rc;
103
}
119
}
104
 
120
 
105
static int udebug_rp_go(call_t *call, phone_t *phone)
121
static int udebug_rp_go(call_t *call, phone_t *phone)
106
{
122
{
107
    thread_t *t;
123
    thread_t *t;
Line 123... Line 139...
123
        spinlock_unlock(&threads_lock);
139
        spinlock_unlock(&threads_lock);
124
        interrupts_restore(ipl);
140
        interrupts_restore(ipl);
125
        return ENOENT;
141
        return ENOENT;
126
    }
142
    }
127
 
143
 
-
 
144
    if ((t->debug_active != true) || (t->debug_stop != true)) {
-
 
145
        /* Not in debugging session or already has GO */
-
 
146
        spinlock_unlock(&threads_lock);
-
 
147
        interrupts_restore(ipl);       
-
 
148
        return EBUSY;
-
 
149
    }
-
 
150
 
128
    t->debug_go_call = call;
151
    t->debug_go_call = call;
129
    t->debug_stop = false;
152
    t->debug_stop = false;
130
    waitq_wakeup(&t->go_wq, WAKEUP_FIRST);
153
    waitq_wakeup(&t->go_wq, WAKEUP_FIRST);
131
 
154
 
132
    spinlock_unlock(&threads_lock);
155
    spinlock_unlock(&threads_lock);
Line 141... Line 164...
141
    task_t *ta;
164
    task_t *ta;
142
    void *uspace_buffer;
165
    void *uspace_buffer;
143
    unative_t to_copy;
166
    unative_t to_copy;
144
    int rc;
167
    int rc;
145
    ipl_t ipl;
168
    ipl_t ipl;
-
 
169
    unative_t buffer[6];
146
 
170
 
147
    klog_printf("debug_args_read()");
171
    klog_printf("debug_args_read()");
148
    // FIXME: verify task/thread state
-
 
149
 
172
 
150
    ta = get_lock_callee_task(phone);
173
    ta = get_lock_callee_task(phone);
151
    klog_printf("task %llu", ta->taskid);
174
    klog_printf("task %llu", ta->taskid);
152
    spinlock_unlock(&ta->lock);
175
    spinlock_unlock(&ta->lock);
153
 
176
 
154
    t = (thread_t *) IPC_GET_ARG2(call->data);
177
    t = (thread_t *) IPC_GET_ARG2(call->data);
155
 
178
 
156
    ipl = interrupts_disable();
179
    ipl = interrupts_disable();
157
    spinlock_lock(&threads_lock);
180
    spinlock_lock(&threads_lock);
158
 
181
 
-
 
182
    /* Verify that 't' exists and belongs to task 'ta' */
159
    if (!thread_exists(t)) {
183
    if (!thread_exists(t) || (t->task != ta)) {
160
        spinlock_unlock(&threads_lock);
184
        spinlock_unlock(&threads_lock);
161
        interrupts_restore(ipl);
185
        interrupts_restore(ipl);
162
        return ENOENT;
186
        return ENOENT;
163
    }
187
    }
164
 
188
 
-
 
189
    //FIXME: additionally we need to verify that we are inside a syscall
-
 
190
    if ((t->debug_active != true) || (t->debug_stop != true)) {
-
 
191
        /* Not in debugging session or has GO */
-
 
192
        spinlock_unlock(&threads_lock);
-
 
193
        interrupts_restore(ipl);       
-
 
194
        return EBUSY;
-
 
195
    }
-
 
196
 
165
    // FIXME: copy to a local buffer before releasing the lock
197
    /* Copy to a local buffer before releasing the lock */
-
 
198
    memcpy(buffer, t->syscall_args, 6 * sizeof(unative_t));
-
 
199
 
166
    spinlock_unlock(&threads_lock);
200
    spinlock_unlock(&threads_lock);
167
    interrupts_restore(ipl);
201
    interrupts_restore(ipl);
168
 
202
 
-
 
203
    /* Now copy to userspace */
-
 
204
 
169
    uspace_buffer = (void *)IPC_GET_ARG3(call->data);
205
    uspace_buffer = (void *)IPC_GET_ARG3(call->data);
170
    to_copy = IPC_GET_ARG4(call->data);
206
    to_copy = IPC_GET_ARG4(call->data);
171
    if (to_copy > 6 * sizeof(unative_t)) to_copy = 6 * sizeof(unative_t);
207
    if (to_copy > 6 * sizeof(unative_t)) to_copy = 6 * sizeof(unative_t);
172
 
208
 
173
    rc = copy_to_uspace(uspace_buffer, t->syscall_args, to_copy);
209
    rc = copy_to_uspace(uspace_buffer, buffer, to_copy);
174
    if (rc != 0) {
210
    if (rc != 0) {
175
        spinlock_unlock(&ta->lock);
211
        spinlock_unlock(&ta->lock);
176
        klog_printf("debug_args_read() - copy failed");
212
        klog_printf("debug_args_read() - copy failed");
177
        return rc;
213
        return rc;
178
    }
214
    }
Line 193... Line 229...
193
    istate_t *state;
229
    istate_t *state;
194
    istate_t state_copy;
230
    istate_t state_copy;
195
    ipl_t ipl;
231
    ipl_t ipl;
196
 
232
 
197
    klog_printf("debug_regs_read()");
233
    klog_printf("debug_regs_read()");
198
    // FIXME: verify task/thread state
-
 
199
 
234
 
200
    ta = get_lock_callee_task(phone);
235
    ta = get_lock_callee_task(phone);
201
    spinlock_unlock(&ta->lock);
236
    spinlock_unlock(&ta->lock);
-
 
237
    //FIXME: don't lock ta
202
 
238
 
203
    ipl = interrupts_disable();
239
    ipl = interrupts_disable();
204
    spinlock_lock(&threads_lock);
240
    spinlock_lock(&threads_lock);
205
 
241
 
206
    t = (thread_t *) IPC_GET_ARG2(call->data);
242
    t = (thread_t *) IPC_GET_ARG2(call->data);
-
 
243
 
-
 
244
    /* Verify that 't' exists and belongs to task 'ta' */
207
    if (!thread_exists(t)) {
245
    if (!thread_exists(t) || (t->task != ta)) {
-
 
246
        spinlock_unlock(&threads_lock);
-
 
247
        interrupts_restore(ipl);
208
        return ENOENT;
248
        return ENOENT;
209
    }
249
    }
210
 
250
 
-
 
251
    if ((t->debug_active != true) || (t->debug_stop != true)) {
-
 
252
        /* Not in debugging session or has GO */
-
 
253
        spinlock_unlock(&threads_lock);
-
 
254
        interrupts_restore(ipl);       
-
 
255
        return EBUSY;
-
 
256
    }
-
 
257
 
211
    state = t->uspace_state;
258
    state = t->uspace_state;
212
    if (state == NULL) {
259
    if (state == NULL) {
213
        spinlock_unlock(&threads_lock);
260
        spinlock_unlock(&threads_lock);
214
        interrupts_restore(ipl);
261
        interrupts_restore(ipl);
215
        klog_printf("debug_regs_read() - istate not available");
262
        klog_printf("debug_regs_read() - istate not available");
Line 262... Line 309...
262
    if (rc != 0) {
309
    if (rc != 0) {
263
        klog_printf("debug_regs_write() - copy failed");
310
        klog_printf("debug_regs_write() - copy failed");
264
        return rc;
311
        return rc;
265
    }
312
    }
266
 
313
 
267
    // FIXME: verify task/thread state
-
 
268
 
-
 
269
    ta = get_lock_callee_task(phone);
314
    ta = get_lock_callee_task(phone);
270
    spinlock_unlock(&ta->lock);
315
    spinlock_unlock(&ta->lock);
-
 
316
    //FIXME: don't lock ta
271
 
317
 
272
    /* Now try to change the thread's uspace_state */
318
    /* Now try to change the thread's uspace_state */
273
 
319
 
274
    ipl = interrupts_disable();
320
    ipl = interrupts_disable();
275
    spinlock_lock(&threads_lock);
321
    spinlock_lock(&threads_lock);
276
 
322
 
277
    t = (thread_t *) IPC_GET_ARG2(call->data);
323
    t = (thread_t *) IPC_GET_ARG2(call->data);
-
 
324
 
-
 
325
    /* Verify that 't' exists and belongs to task 'ta' */
278
    if (!thread_exists(t)) {
326
    if (!thread_exists(t) || (t->task != ta)) {
279
        spinlock_unlock(&threads_lock);
327
        spinlock_unlock(&threads_lock);
280
        interrupts_restore(ipl);
328
        interrupts_restore(ipl);
281
        return ENOENT;
329
        return ENOENT;
282
    }
330
    }
283
 
331
 
-
 
332
    if ((t->debug_active != true) || (t->debug_stop != true)) {
-
 
333
        /* Not in debugging session or has GO */
-
 
334
        spinlock_unlock(&threads_lock);
-
 
335
        interrupts_restore(ipl);       
-
 
336
        return EBUSY;
-
 
337
    }
-
 
338
 
284
    state = t->uspace_state;
339
    state = t->uspace_state;
285
    if (state == NULL) {
340
    if (state == NULL) {
286
        spinlock_unlock(&threads_lock);
341
        spinlock_unlock(&threads_lock);
287
        interrupts_restore(ipl);
342
        interrupts_restore(ipl);
288
        klog_printf("debug_regs_write() - istate not available");
343
        klog_printf("debug_regs_write() - istate not available");
Line 318... Line 373...
318
    ipl_t ipl;
373
    ipl_t ipl;
319
    unative_t *buffer;
374
    unative_t *buffer;
320
    int flags;
375
    int flags;
321
 
376
 
322
    klog_printf("debug_thread_read()");
377
    klog_printf("debug_thread_read()");
323
    // FIXME: verify task/thread state
-
 
324
 
378
 
325
    ipl = interrupts_disable();
379
    ipl = interrupts_disable();
326
    ta = get_lock_callee_task(phone);
380
    ta = get_lock_callee_task(phone);
327
 
381
 
-
 
382
    /* Verify task state */
-
 
383
    if (ta->dt_state != UDEBUG_TS_ACTIVE) {
-
 
384
        spinlock_unlock(&ta->lock);
-
 
385
        interrupts_restore(ipl);
-
 
386
        return EBUSY;
-
 
387
    }
-
 
388
 
328
    /* Count the threads first */
389
    /* Count the threads first */
329
 
390
 
330
    num_threads = 0;
391
    num_threads = 0;
331
    for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
392
    for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
332
        /* Count all threads, to be on the safe side */
393
        /* Count all threads, to be on the safe side */
Line 388... Line 449...
388
    unative_t to_copy;
449
    unative_t to_copy;
389
    int rc;
450
    int rc;
390
    void *buffer;
451
    void *buffer;
391
 
452
 
392
    klog_printf("udebug_rp_mem_write()");
453
    klog_printf("udebug_rp_mem_write()");
393
    // FIXME: verify task/thread state
-
 
394
 
454
 
395
    uspace_data = (void *)IPC_GET_ARG2(call->data);
455
    uspace_data = (void *)IPC_GET_ARG2(call->data);
396
    to_copy = IPC_GET_ARG4(call->data);
456
    to_copy = IPC_GET_ARG4(call->data);
397
 
457
 
398
    buffer = malloc(to_copy, 0); // ???
458
    buffer = malloc(to_copy, 0); // ???
Line 484... Line 544...
484
{
544
{
485
    void *uspace_dst;
545
    void *uspace_dst;
486
    unsigned size;
546
    unsigned size;
487
    void *buffer;
547
    void *buffer;
488
    int rc;
548
    int rc;
-
 
549
    udebug_task_state_t dts;
489
 
550
 
490
    klog_printf("udebug_receive_mem_write()");
551
    klog_printf("udebug_receive_mem_write()");
-
 
552
 
-
 
553
    /* Verify task state */
-
 
554
    spinlock_lock(&TASK->lock);
-
 
555
    dts = TASK->dt_state;
-
 
556
    spinlock_unlock(&TASK->lock);
-
 
557
 
-
 
558
    if (dts != UDEBUG_TS_ACTIVE) {
-
 
559
        IPC_SET_RETVAL(call->data, EBUSY);
-
 
560
        ipc_answer(&TASK->kernel_box, call);
-
 
561
        return;
-
 
562
    }
-
 
563
   
491
    uspace_dst = (void *)IPC_GET_ARG3(call->data);
564
    uspace_dst = (void *)IPC_GET_ARG3(call->data);
492
    size = IPC_GET_ARG4(call->data);
565
    size = IPC_GET_ARG4(call->data);
493
 
566
 
494
    buffer = call->buffer;
567
    buffer = call->buffer;
495
    klog_printf("dst=%u, size=%u", uspace_dst, size);
568
    klog_printf("dst=%u, size=%u", uspace_dst, size);
Line 497... Line 570...
497
    /* NOTE: this is not strictly from a syscall... but that shouldn't
570
    /* NOTE: this is not strictly from a syscall... but that shouldn't
498
     * be a problem */
571
     * be a problem */
499
    rc = copy_to_uspace(uspace_dst, buffer, size);
572
    rc = copy_to_uspace(uspace_dst, buffer, size);
500
    if (rc) {
573
    if (rc) {
501
        IPC_SET_RETVAL(call->data, rc);
574
        IPC_SET_RETVAL(call->data, rc);
-
 
575
        ipc_answer(&TASK->kernel_box, call);
502
        return;
576
        return;
503
    }
577
    }
504
 
578
 
505
    IPC_SET_RETVAL(call->data, 0);
579
    IPC_SET_RETVAL(call->data, 0);
506
 
580