Rev 4605 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4605 | Rev 4616 | ||
---|---|---|---|
Line 283... | Line 283... | ||
283 | call->buffer = buffer; |
283 | call->buffer = buffer; |
284 | 284 | ||
285 | ipc_answer(&TASK->kb.box, call); |
285 | ipc_answer(&TASK->kb.box, call); |
286 | } |
286 | } |
287 | 287 | ||
- | 288 | ||
- | 289 | ||
- | 290 | /**************************/ |
|
- | 291 | /*** CHECKPOINTING ***/ |
|
- | 292 | /**************************/ |
|
- | 293 | ||
- | 294 | ||
- | 295 | static void udebug_receive_thread_get_thread_struct(call_t *call) |
|
- | 296 | { |
|
- | 297 | unative_t to_copy; |
|
- | 298 | unative_t total_bytes; |
|
- | 299 | thread_t *t = (thread_t *)IPC_GET_ARG3(call->data); |
|
- | 300 | void *buffer; |
|
- | 301 | ||
- | 302 | unative_t uspace_addr = IPC_GET_ARG2(call->data); |
|
- | 303 | size_t buf_size = IPC_GET_ARG4(call->data); |
|
- | 304 | ||
- | 305 | if (buf_size < sizeof(thread_t)) |
|
- | 306 | { |
|
- | 307 | to_copy = 0; |
|
- | 308 | total_bytes = sizeof(thread_t); |
|
- | 309 | } |
|
- | 310 | else |
|
- | 311 | { |
|
- | 312 | udebug_thread_get_thread_struct(t, &buffer); |
|
- | 313 | to_copy = sizeof(thread_t); |
|
- | 314 | total_bytes = sizeof(thread_t); |
|
- | 315 | } |
|
- | 316 | ||
- | 317 | IPC_SET_RETVAL(call->data, 0); |
|
- | 318 | IPC_SET_ARG1(call->data, uspace_addr); |
|
- | 319 | IPC_SET_ARG2(call->data, to_copy); |
|
- | 320 | IPC_SET_ARG3(call->data, total_bytes); |
|
- | 321 | ||
- | 322 | if (to_copy > 0) |
|
- | 323 | call->buffer = buffer; |
|
- | 324 | else |
|
- | 325 | call->buffer = NULL; |
|
- | 326 | ||
- | 327 | ipc_answer(&TASK->kb.box, call); |
|
- | 328 | } |
|
- | 329 | ||
- | 330 | static void udebug_receive_thread_copy_kstack(call_t *call) |
|
- | 331 | { |
|
- | 332 | void *buffer; |
|
- | 333 | unative_t uspace_addr = IPC_GET_ARG2(call->data); |
|
- | 334 | size_t buf_size = IPC_GET_ARG3(call->data); |
|
- | 335 | thread_t *t = (thread_t *)IPC_GET_ARG4(call->data); |
|
- | 336 | size_t copied; |
|
- | 337 | ||
- | 338 | size_t kstack_size = PAGE_SIZE;//(uintptr_t)t->saved_context.sp - (uintptr_t)t->kstack; |
|
- | 339 | ||
- | 340 | if (buf_size >= kstack_size) |
|
- | 341 | { |
|
- | 342 | udebug_copy_kstack(t->kstack, &buffer, buf_size); |
|
- | 343 | copied = kstack_size; |
|
- | 344 | } |
|
- | 345 | else |
|
- | 346 | copied = 0; |
|
- | 347 | ||
- | 348 | IPC_SET_RETVAL(call->data, 0); |
|
- | 349 | IPC_SET_ARG1(call->data, uspace_addr); |
|
- | 350 | IPC_SET_ARG2(call->data, copied); |
|
- | 351 | IPC_SET_ARG3(call->data, kstack_size); // needed |
|
- | 352 | ||
- | 353 | if (copied > 0) |
|
- | 354 | call->buffer = (void *)buffer; |
|
- | 355 | else |
|
- | 356 | call->buffer = NULL; |
|
- | 357 | ||
- | 358 | ipc_answer(&TASK->kb.box, call); |
|
- | 359 | } |
|
- | 360 | ||
- | 361 | static void udebug_receive_task_mem_areas_read(call_t *call) |
|
- | 362 | { |
|
- | 363 | unative_t uspace_addr; |
|
- | 364 | unative_t to_copy; |
|
- | 365 | unsigned total_bytes; |
|
- | 366 | unsigned buf_size; |
|
- | 367 | void *buffer; |
|
- | 368 | size_t n; |
|
- | 369 | int rc; |
|
- | 370 | ||
- | 371 | uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */ |
|
- | 372 | buf_size = IPC_GET_ARG3(call->data); /* Dest. buffer size */ |
|
- | 373 | ||
- | 374 | rc = udebug_task_get_memory_areas(&buffer, buf_size, &n); |
|
- | 375 | if (rc < 0) { |
|
- | 376 | IPC_SET_RETVAL(call->data, rc); |
|
- | 377 | ipc_answer(&TASK->kb.box, call); |
|
- | 378 | return; |
|
- | 379 | } |
|
- | 380 | ||
- | 381 | total_bytes = n; |
|
- | 382 | ||
- | 383 | /* Copy MAX(buf_size, total_bytes) bytes */ |
|
- | 384 | ||
- | 385 | if (buf_size > total_bytes) |
|
- | 386 | to_copy = total_bytes; |
|
- | 387 | else |
|
- | 388 | to_copy = buf_size; |
|
- | 389 | ||
- | 390 | /* |
|
- | 391 | * Make use of call->buffer to transfer data to caller's userspace |
|
- | 392 | */ |
|
- | 393 | ||
- | 394 | IPC_SET_RETVAL(call->data, 0); |
|
- | 395 | /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that |
|
- | 396 | same code in process_answer() can be used |
|
- | 397 | (no way to distinguish method in answer) */ |
|
- | 398 | IPC_SET_ARG1(call->data, uspace_addr); |
|
- | 399 | IPC_SET_ARG2(call->data, to_copy); |
|
- | 400 | ||
- | 401 | IPC_SET_ARG3(call->data, total_bytes); |
|
- | 402 | call->buffer = buffer; |
|
- | 403 | ||
- | 404 | ipc_answer(&TASK->kb.box, call); |
|
- | 405 | } |
|
- | 406 | ||
- | 407 | static void udebug_receive_mem_write(call_t *call) |
|
- | 408 | { |
|
- | 409 | size_t size = (size_t)IPC_GET_ARG3(call->data); |
|
- | 410 | void *start = (void *)IPC_GET_ARG4(call->data); |
|
- | 411 | ||
- | 412 | udebug_mem_write(call->buffer, start, size); |
|
- | 413 | ||
- | 414 | IPC_SET_RETVAL(call->data, 0); |
|
- | 415 | ipc_answer(&TASK->kb.box, call); |
|
- | 416 | } |
|
- | 417 | ||
- | 418 | static void udebug_receive_thread_restore_struct(call_t *call) |
|
- | 419 | { |
|
- | 420 | thread_t *t = (thread_t *)IPC_GET_ARG3(call->data); |
|
- | 421 | ||
- | 422 | udebug_restore_thread_struct(call->buffer, t); |
|
- | 423 | ||
- | 424 | IPC_SET_RETVAL(call->data, 0); |
|
- | 425 | ||
- | 426 | ipc_answer(&TASK->kb.box, call); |
|
- | 427 | } |
|
- | 428 | ||
- | 429 | static void udebug_receive_restore_kstack(call_t *call) |
|
- | 430 | { |
|
- | 431 | size_t size = (size_t)IPC_GET_ARG3(call->data); |
|
- | 432 | thread_t *t = (thread_t *)IPC_GET_ARG4(call->data); |
|
- | 433 | ||
- | 434 | udebug_restore_kstack(call->buffer, size, t); |
|
- | 435 | ||
- | 436 | IPC_SET_RETVAL(call->data, 0); |
|
- | 437 | ipc_answer(&TASK->kb.box, call); |
|
- | 438 | ||
- | 439 | } |
|
- | 440 | ||
288 | /** Handle a debug call received on the kernel answerbox. |
441 | /** Handle a debug call received on the kernel answerbox. |
289 | * |
442 | * |
290 | * This is called by the kbox servicing thread. Verifies that the sender |
443 | * This is called by the kbox servicing thread. Verifies that the sender |
291 | * is indeed the debugger and calls the appropriate processing function. |
444 | * is indeed the debugger and calls the appropriate processing function. |
292 | */ |
445 | */ |
Line 334... | Line 487... | ||
334 | udebug_receive_args_read(call); |
487 | udebug_receive_args_read(call); |
335 | break; |
488 | break; |
336 | case UDEBUG_M_MEM_READ: |
489 | case UDEBUG_M_MEM_READ: |
337 | udebug_receive_mem_read(call); |
490 | udebug_receive_mem_read(call); |
338 | break; |
491 | break; |
- | 492 | ||
- | 493 | /* CHECKPOINTING */ |
|
- | 494 | case UDEBUG_M_TASK_MEM_AREAS_READ: |
|
- | 495 | udebug_receive_task_mem_areas_read(call); |
|
- | 496 | break; |
|
- | 497 | case UDEBUG_M_MEM_WRITE: |
|
- | 498 | udebug_receive_mem_write(call); |
|
- | 499 | break; |
|
- | 500 | case UDEBUG_M_THREAD_COPY_KSTACK: |
|
- | 501 | udebug_receive_thread_copy_kstack(call); |
|
- | 502 | break; |
|
- | 503 | case UDEBUG_M_RESTORE_KSTACK: |
|
- | 504 | udebug_receive_restore_kstack(call); |
|
- | 505 | break; |
|
- | 506 | case UDEBUG_M_THREAD_GET_THREAD_STRUCT: |
|
- | 507 | udebug_receive_thread_get_thread_struct(call); |
|
- | 508 | break; |
|
- | 509 | case UDEBUG_M_THREAD_RESTORE_THREAD_STRUCT: |
|
- | 510 | udebug_receive_thread_restore_struct(call); |
|
- | 511 | break; |
|
339 | } |
512 | } |
340 | } |
513 | } |
341 | 514 | ||
342 | /** @} |
515 | /** @} |
343 | */ |
516 | */ |