Rev 2812 | Rev 3011 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2812 | Rev 2813 | ||
---|---|---|---|
Line 40... | Line 40... | ||
40 | #include <debug.h> |
40 | #include <debug.h> |
41 | #include <ipc/ipc.h> |
41 | #include <ipc/ipc.h> |
42 | #include <ipc/sysipc.h> |
42 | #include <ipc/sysipc.h> |
43 | #include <ipc/irq.h> |
43 | #include <ipc/irq.h> |
44 | #include <ipc/ipcrsc.h> |
44 | #include <ipc/ipcrsc.h> |
- | 45 | #include <udebug/udebug_ipc.h> |
|
45 | #include <arch/interrupt.h> |
46 | #include <arch/interrupt.h> |
46 | #include <print.h> |
47 | #include <print.h> |
47 | #include <syscall/copy.h> |
48 | #include <syscall/copy.h> |
48 | #include <security/cap.h> |
49 | #include <security/cap.h> |
49 | #include <mm/as.h> |
50 | #include <mm/as.h> |
Line 288... | Line 289... | ||
288 | answer->buffer = NULL; |
289 | answer->buffer = NULL; |
289 | } |
290 | } |
290 | return 0; |
291 | return 0; |
291 | } |
292 | } |
292 | 293 | ||
293 | static task_t *get_lock_callee_task(phone_t *phone) |
- | |
294 | { |
- | |
295 | answerbox_t *answerbox; |
- | |
296 | task_t *ta; |
- | |
297 | - | ||
298 | // FIXME: locking!!! |
- | |
299 | - | ||
300 | answerbox = phone->callee; |
- | |
301 | ta = answerbox->task; |
- | |
302 | - | ||
303 | spinlock_lock(&ta->lock); |
- | |
304 | - | ||
305 | return ta; |
- | |
306 | } |
- | |
307 | - | ||
308 | static thread_t *get_task_thread_by_id(task_t *ta, thread_id_t tid) |
- | |
309 | { |
- | |
310 | thread_t *t; |
- | |
311 | link_t *cur; |
- | |
312 | - | ||
313 | for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) { |
- | |
314 | t = list_get_instance(cur, thread_t, th_link); |
- | |
315 | if (tid == t->tid) return t; |
- | |
316 | } |
- | |
317 | - | ||
318 | return NULL; |
- | |
319 | } |
- | |
320 | - | ||
321 | #include <console/klog.h> |
- | |
322 | - | ||
323 | static int debug_begin(call_t *call, phone_t *phone) |
- | |
324 | { |
- | |
325 | task_t *ta; |
- | |
326 | - | ||
327 | klog_printf("debug_begin()"); |
- | |
328 | - | ||
329 | ta = get_lock_callee_task(phone); |
- | |
330 | klog_printf("debugging task %llu", ta->taskid); |
- | |
331 | - | ||
332 | if (ta->being_debugged != false) { |
- | |
333 | spinlock_unlock(&ta->lock); |
- | |
334 | klog_printf("debug_begin(): busy error"); |
- | |
335 | return EBUSY; |
- | |
336 | } |
- | |
337 | - | ||
338 | ta->being_debugged = true; |
- | |
339 | ta->stop_request = true; |
- | |
340 | ta->debug_begin_call = call; |
- | |
341 | - | ||
342 | if (ta->not_stoppable_count == 0) { |
- | |
343 | ta->debug_begin_call = NULL; |
- | |
344 | ta->stop_request = false; |
- | |
345 | spinlock_unlock(&ta->lock); |
- | |
346 | klog_printf("debug_begin(): immediate backsend"); |
- | |
347 | return 1; /* actually we need backsend with 0 retval */ |
- | |
348 | } |
- | |
349 | - | ||
350 | spinlock_unlock(&ta->lock); |
- | |
351 | - | ||
352 | klog_printf("debug_begin() done (wait for stoppability)"); |
- | |
353 | return 0; |
- | |
354 | } |
- | |
355 | - | ||
356 | static int debug_go(call_t *call, phone_t *phone) |
- | |
357 | { |
- | |
358 | thread_t *t; |
- | |
359 | task_t *ta; |
- | |
360 | - | ||
361 | klog_printf("debug_go()"); |
- | |
362 | ta = get_lock_callee_task(phone); |
- | |
363 | - | ||
364 | ta->debug_go_call = call; |
- | |
365 | t = get_task_thread_by_id(ta, IPC_GET_ARG2(call->data)); |
- | |
366 | if (t == NULL) { |
- | |
367 | spinlock_unlock(&ta->lock); |
- | |
368 | return ENOENT; |
- | |
369 | } |
- | |
370 | - | ||
371 | klog_printf("debug_go(): waitq_wakeup"); |
- | |
372 | waitq_wakeup(&t->go_wq, WAKEUP_FIRST); |
- | |
373 | - | ||
374 | spinlock_unlock(&ta->lock); |
- | |
375 | - | ||
376 | return 0; /* no backsend */ |
- | |
377 | } |
- | |
378 | - | ||
379 | static int debug_args_read(call_t *call, phone_t *phone) |
- | |
380 | { |
- | |
381 | thread_t *t; |
- | |
382 | task_t *ta; |
- | |
383 | void *uspace_buffer; |
- | |
384 | unative_t to_copy; |
- | |
385 | int rc; |
- | |
386 | - | ||
387 | klog_printf("debug_args_read()"); |
- | |
388 | // FIXME: verify task/thread state |
- | |
389 | - | ||
390 | ta = get_lock_callee_task(phone); |
- | |
391 | klog_printf("task %llu", ta->taskid); |
- | |
392 | t = get_task_thread_by_id(ta, IPC_GET_ARG2(call->data)); |
- | |
393 | if (t == NULL) { |
- | |
394 | spinlock_unlock(&ta->lock); |
- | |
395 | return ENOENT; |
- | |
396 | } |
- | |
397 | - | ||
398 | uspace_buffer = (void *)IPC_GET_ARG3(call->data); |
- | |
399 | to_copy = IPC_GET_ARG4(call->data); |
- | |
400 | if (to_copy > 6 * sizeof(unative_t)) to_copy = 6 * sizeof(unative_t); |
- | |
401 | - | ||
402 | rc = copy_to_uspace(uspace_buffer, t->syscall_args, to_copy); |
- | |
403 | if (rc != 0) { |
- | |
404 | spinlock_unlock(&ta->lock); |
- | |
405 | klog_printf("debug_args_read() - copy failed"); |
- | |
406 | return rc; |
- | |
407 | } |
- | |
408 | - | ||
409 | spinlock_unlock(&ta->lock); |
- | |
410 | - | ||
411 | IPC_SET_ARG1(call->data, to_copy); |
- | |
412 | - | ||
413 | klog_printf("debug_args_read() done"); |
- | |
414 | return 1; /* actually need becksend with retval 0 */ |
- | |
415 | } |
- | |
416 | - | ||
417 | static int debug_thread_read(call_t *call, phone_t *phone) |
- | |
418 | { |
- | |
419 | thread_t *t; |
- | |
420 | link_t *cur; |
- | |
421 | task_t *ta; |
- | |
422 | unative_t *uspace_buffer; |
- | |
423 | unative_t to_copy; |
- | |
424 | int rc; |
- | |
425 | unsigned copied, total; |
- | |
426 | unsigned buf_size; |
- | |
427 | unative_t tid; |
- | |
428 | - | ||
429 | klog_printf("debug_thread_read()"); |
- | |
430 | // FIXME: verify task/thread state |
- | |
431 | - | ||
432 | ta = get_lock_callee_task(phone); |
- | |
433 | klog_printf("task %llu", ta->taskid); |
- | |
434 | - | ||
435 | uspace_buffer = (void *)IPC_GET_ARG2(call->data); |
- | |
436 | buf_size = IPC_GET_ARG3(call->data); |
- | |
437 | - | ||
438 | copied = total = 0; |
- | |
439 | for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) { |
- | |
440 | t = list_get_instance(cur, thread_t, th_link); |
- | |
441 | - | ||
442 | /* Not interested in kernel threads */ |
- | |
443 | if ((t->flags & THREAD_FLAG_USPACE) == 0) |
- | |
444 | continue; |
- | |
445 | - | ||
446 | //FIXME: id cropped!! |
- | |
447 | tid = (unative_t) t->tid; |
- | |
448 | - | ||
449 | to_copy = sizeof(unative_t); |
- | |
450 | if (copied + to_copy >= buf_size) |
- | |
451 | to_copy = buf_size - copied; |
- | |
452 | - | ||
453 | if (to_copy > 0) { |
- | |
454 | rc = copy_to_uspace(uspace_buffer, &tid, to_copy); |
- | |
455 | if (rc != 0) { |
- | |
456 | spinlock_unlock(&ta->lock); |
- | |
457 | klog_printf("debug_thread_read() - copy failed"); |
- | |
458 | return rc; |
- | |
459 | } |
- | |
460 | } |
- | |
461 | - | ||
462 | ++uspace_buffer; |
- | |
463 | total += sizeof(unative_t); |
- | |
464 | copied += to_copy; |
- | |
465 | } |
- | |
466 | - | ||
467 | spinlock_unlock(&ta->lock); |
- | |
468 | - | ||
469 | IPC_SET_ARG1(call->data, copied); |
- | |
470 | IPC_SET_ARG2(call->data, total); |
- | |
471 | - | ||
472 | klog_printf("debug_thread_read() done"); |
- | |
473 | return 1; /* actually need becksend with retval 0 */ |
- | |
474 | } |
- | |
475 | - | ||
476 | #include <udebug.h> |
- | |
477 | - | ||
478 | static int debug_request_preprocess(call_t *call, phone_t *phone) |
- | |
479 | { |
- | |
480 | int rc; |
- | |
481 | - | ||
482 | switch (IPC_GET_ARG1(call->data)) { |
- | |
483 | case UDEBUG_M_BEGIN: |
- | |
484 | rc = debug_begin(call, phone); |
- | |
485 | return rc; |
- | |
486 | case UDEBUG_M_GO: |
- | |
487 | rc = debug_go(call, phone); |
- | |
488 | return rc; |
- | |
489 | case UDEBUG_M_ARGS_READ: |
- | |
490 | rc = debug_args_read(call, phone); |
- | |
491 | return rc; |
- | |
492 | case UDEBUG_M_THREAD_READ: |
- | |
493 | rc = debug_thread_read(call, phone); |
- | |
494 | return rc; |
- | |
495 | default: |
- | |
496 | break; |
- | |
497 | } |
- | |
498 | - | ||
499 | return 0; |
- | |
500 | } |
- | |
501 | - | ||
502 | /** Called before the request is sent. |
294 | /** Called before the request is sent. |
503 | * |
295 | * |
504 | * @param call Call structure with the request. |
296 | * @param call Call structure with the request. |
505 | * @param phone Phone that the call will be sent through. |
297 | * @param phone Phone that the call will be sent through. |
506 | * |
298 | * |
Line 548... | Line 340... | ||
548 | return rc; |
340 | return rc; |
549 | } |
341 | } |
550 | break; |
342 | break; |
551 | case IPC_M_DEBUG_ALL: |
343 | case IPC_M_DEBUG_ALL: |
552 | /* actually need possibility of backsend with 0 result code */ |
344 | /* actually need possibility of backsend with 0 result code */ |
553 | rc = debug_request_preprocess(call, phone); |
345 | rc = udebug_request_preprocess(call, phone); |
554 | return rc; |
346 | return rc; |
555 | default: |
347 | default: |
556 | break; |
348 | break; |
557 | } |
349 | } |
558 | return 0; |
350 | return 0; |
Line 797... | Line 589... | ||
797 | sizeof(call->data.args)); |
589 | sizeof(call->data.args)); |
798 | if (rc != 0) { |
590 | if (rc != 0) { |
799 | ipc_call_free(call); |
591 | ipc_call_free(call); |
800 | return (unative_t) rc; |
592 | return (unative_t) rc; |
801 | } |
593 | } |
802 | if (TASK->being_debugged) |
- | |
803 | klog_printf("call_async_slow: phone=%u, uspace_ptr=%u, arg0=%u", |
- | |
804 | phoneid, (unsigned)data, call->data.args[0]); |
- | |
805 | if (!(res = request_preprocess(call, phone))) |
594 | if (!(res = request_preprocess(call, phone))) |
806 | ipc_call(phone, call); |
595 | ipc_call(phone, call); |
807 | else |
596 | else |
808 | ipc_backsend_err(phone, call, res); |
597 | ipc_backsend_err(phone, call, res); |
809 | 598 |