Rev 2812 | Rev 2892 | 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 | ||