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 | } |