Rev 3014 | Rev 3018 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3014 | Rev 3016 | ||
|---|---|---|---|
| Line 135... | Line 135... | ||
| 135 | thread_t *t; |
135 | thread_t *t; |
| 136 | link_t *cur; |
136 | link_t *cur; |
| 137 | 137 | ||
| 138 | klog_printf("udebug_begin()"); |
138 | klog_printf("udebug_begin()"); |
| 139 | 139 | ||
| 140 | ipl = interrupts_disable(); |
140 | mutex_lock(&TASK->udebug.lock); |
| 141 | klog_printf("debugging task %llu", TASK->taskid); |
141 | klog_printf("debugging task %llu", TASK->taskid); |
| 142 | 142 | ||
| 143 | spinlock_lock(&TASK->lock); |
- | |
| 144 | - | ||
| 145 | if (TASK->udebug.dt_state != UDEBUG_TS_INACTIVE) { |
143 | if (TASK->udebug.dt_state != UDEBUG_TS_INACTIVE) { |
| 146 | spinlock_unlock(&TASK->lock); |
144 | mutex_unlock(&TASK->udebug.lock); |
| 147 | interrupts_restore(ipl); |
- | |
| 148 | klog_printf("udebug_begin(): busy error"); |
145 | klog_printf("udebug_begin(): busy error"); |
| 149 | 146 | ||
| 150 | return EBUSY; |
147 | return EBUSY; |
| 151 | } |
148 | } |
| 152 | 149 | ||
| Line 165... | Line 162... | ||
| 165 | /* Set debug_active on all of the task's userspace threads */ |
162 | /* Set debug_active on all of the task's userspace threads */ |
| 166 | 163 | ||
| 167 | for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) { |
164 | for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) { |
| 168 | t = list_get_instance(cur, thread_t, th_link); |
165 | t = list_get_instance(cur, thread_t, th_link); |
| 169 | 166 | ||
| - | 167 | ipl = interrupts_disable(); |
|
| 170 | spinlock_lock(&t->debug_lock); |
168 | spinlock_lock(&t->debug_lock); |
| 171 | if ((t->flags & THREAD_FLAG_USPACE) != 0) |
169 | if ((t->flags & THREAD_FLAG_USPACE) != 0) |
| 172 | t->debug_active = true; |
170 | t->debug_active = true; |
| 173 | spinlock_unlock(&t->debug_lock); |
171 | spinlock_unlock(&t->debug_lock); |
| - | 172 | interrupts_restore(ipl); |
|
| 174 | } |
173 | } |
| 175 | 174 | ||
| 176 | spinlock_unlock(&TASK->lock); |
175 | mutex_unlock(&TASK->udebug.lock); |
| 177 | interrupts_restore(ipl); |
- | |
| 178 | 176 | ||
| 179 | klog_printf("udebug_begin() done (%s)", |
177 | klog_printf("udebug_begin() done (%s)", |
| 180 | reply ? "reply" : "stoppability wait"); |
178 | reply ? "reply" : "stoppability wait"); |
| 181 | 179 | ||
| 182 | return reply; |
180 | return reply; |
| 183 | } |
181 | } |
| 184 | 182 | ||
| 185 | int udebug_end(void) |
183 | int udebug_end(void) |
| 186 | { |
184 | { |
| 187 | ipl_t ipl; |
- | |
| 188 | int rc; |
185 | int rc; |
| 189 | 186 | ||
| 190 | klog_printf("udebug_end()"); |
187 | klog_printf("udebug_end()"); |
| 191 | 188 | ||
| 192 | ipl = interrupts_disable(); |
- | |
| 193 | spinlock_lock(&TASK->lock); |
189 | mutex_lock(&TASK->udebug.lock); |
| 194 | - | ||
| 195 | rc = udebug_task_cleanup(TASK); |
- | |
| 196 | - | ||
| 197 | klog_printf("task %llu", TASK->taskid); |
190 | klog_printf("task %llu", TASK->taskid); |
| 198 | 191 | ||
| 199 | spinlock_unlock(&TASK->lock); |
- | |
| 200 | interrupts_restore(ipl); |
192 | rc = udebug_task_cleanup(TASK); |
| 201 | 193 | ||
| 202 | if (rc < 0) return EINVAL; |
194 | mutex_unlock(&TASK->udebug.lock); |
| 203 | 195 | ||
| 204 | return 0; |
196 | return rc; |
| 205 | } |
197 | } |
| 206 | 198 | ||
| 207 | int udebug_set_evmask(udebug_evmask_t mask) |
199 | int udebug_set_evmask(udebug_evmask_t mask) |
| 208 | { |
200 | { |
| 209 | ipl_t ipl; |
- | |
| 210 | - | ||
| 211 | klog_printf("udebug_set_mask()"); |
201 | klog_printf("udebug_set_mask()"); |
| 212 | 202 | ||
| 213 | ipl = interrupts_disable(); |
- | |
| 214 | klog_printf("debugging task %llu", TASK->taskid); |
203 | klog_printf("debugging task %llu", TASK->taskid); |
| 215 | 204 | ||
| 216 | spinlock_lock(&TASK->lock); |
205 | mutex_lock(&TASK->udebug.lock); |
| 217 | 206 | ||
| 218 | if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) { |
207 | if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) { |
| 219 | spinlock_unlock(&TASK->lock); |
208 | mutex_unlock(&TASK->udebug.lock); |
| 220 | interrupts_restore(ipl); |
- | |
| 221 | klog_printf("udebug_set_mask(): not active debuging session"); |
209 | klog_printf("udebug_set_mask(): not active debuging session"); |
| 222 | 210 | ||
| 223 | return EINVAL; |
211 | return EINVAL; |
| 224 | } |
212 | } |
| 225 | 213 | ||
| 226 | TASK->udebug.evmask = mask; |
214 | TASK->udebug.evmask = mask; |
| 227 | 215 | ||
| 228 | spinlock_unlock(&TASK->lock); |
216 | mutex_unlock(&TASK->udebug.lock); |
| 229 | interrupts_restore(ipl); |
- | |
| 230 | 217 | ||
| 231 | return 0; |
218 | return 0; |
| 232 | } |
219 | } |
| 233 | 220 | ||
| 234 | 221 | ||
| Line 267... | Line 254... | ||
| 267 | { |
254 | { |
| 268 | ipl_t ipl; |
255 | ipl_t ipl; |
| 269 | int rc; |
256 | int rc; |
| 270 | 257 | ||
| 271 | klog_printf("udebug_stop()"); |
258 | klog_printf("udebug_stop()"); |
| - | 259 | mutex_lock(&TASK->udebug.lock); |
|
| 272 | 260 | ||
| 273 | ipl = interrupts_disable(); |
261 | ipl = interrupts_disable(); |
| 274 | 262 | ||
| 275 | /* |
263 | /* |
| 276 | * On success, this will lock t->debug_lock. Note that this makes sure |
264 | * On success, this will lock t->debug_lock. Note that this makes sure |
| Line 304... | Line 292... | ||
| 304 | IPC_SET_RETVAL(call->data, 0); |
292 | IPC_SET_RETVAL(call->data, 0); |
| 305 | IPC_SET_ARG1(call->data, UDEBUG_EVENT_STOP); |
293 | IPC_SET_ARG1(call->data, UDEBUG_EVENT_STOP); |
| 306 | klog_printf("udebug_stop/ipc_answer"); |
294 | klog_printf("udebug_stop/ipc_answer"); |
| 307 | 295 | ||
| 308 | THREAD->cur_event = UDEBUG_EVENT_STOP; |
296 | THREAD->cur_event = UDEBUG_EVENT_STOP; |
| - | 297 | ||
| 309 | _thread_op_end(t); |
298 | _thread_op_end(t); |
| - | 299 | interrupts_restore(ipl); |
|
| 310 | 300 | ||
| 311 | spinlock_lock(&TASK->lock); |
- | |
| 312 | ipc_answer(&TASK->answerbox, call); |
301 | ipc_answer(&TASK->answerbox, call); |
| 313 | spinlock_unlock(&TASK->lock); |
302 | mutex_unlock(&TASK->udebug.lock); |
| 314 | 303 | ||
| 315 | interrupts_restore(ipl); |
- | |
| 316 | klog_printf("udebog_stop/done"); |
304 | klog_printf("udebog_stop/done"); |
| 317 | return 0; |
305 | return 0; |
| 318 | } |
306 | } |
| 319 | 307 | ||
| 320 | int udebug_thread_read(void **buffer, size_t buf_size, size_t *n) |
308 | int udebug_thread_read(void **buffer, size_t buf_size, size_t *n) |
| Line 331... | Line 319... | ||
| 331 | klog_printf("udebug_thread_read()"); |
319 | klog_printf("udebug_thread_read()"); |
| 332 | 320 | ||
| 333 | /* Allocate a buffer to hold thread IDs */ |
321 | /* Allocate a buffer to hold thread IDs */ |
| 334 | id_buffer = malloc(buf_size, 0); |
322 | id_buffer = malloc(buf_size, 0); |
| 335 | 323 | ||
| 336 | ipl = interrupts_disable(); |
- | |
| 337 | spinlock_lock(&TASK->lock); |
324 | mutex_lock(&TASK->udebug.lock); |
| 338 | 325 | ||
| 339 | /* Verify task state */ |
326 | /* Verify task state */ |
| 340 | if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) { |
327 | if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) { |
| 341 | spinlock_unlock(&TASK->lock); |
328 | mutex_unlock(&TASK->udebug.lock); |
| 342 | interrupts_restore(ipl); |
- | |
| 343 | - | ||
| 344 | return EINVAL; |
329 | return EINVAL; |
| 345 | } |
330 | } |
| 346 | 331 | ||
| - | 332 | ipl = interrupts_disable(); |
|
| - | 333 | spinlock_lock(&TASK->lock); |
|
| 347 | /* Copy down the thread IDs */ |
334 | /* Copy down the thread IDs */ |
| 348 | 335 | ||
| 349 | max_ids = buf_size / sizeof(unative_t); |
336 | max_ids = buf_size / sizeof(unative_t); |
| 350 | copied_ids = 0; |
337 | copied_ids = 0; |
| 351 | 338 | ||
| Line 368... | Line 355... | ||
| 368 | } |
355 | } |
| 369 | 356 | ||
| 370 | spinlock_unlock(&TASK->lock); |
357 | spinlock_unlock(&TASK->lock); |
| 371 | interrupts_restore(ipl); |
358 | interrupts_restore(ipl); |
| 372 | 359 | ||
| - | 360 | mutex_unlock(&TASK->udebug.lock); |
|
| - | 361 | ||
| 373 | *buffer = id_buffer; |
362 | *buffer = id_buffer; |
| 374 | *n = copied_ids * sizeof(unative_t); |
363 | *n = copied_ids * sizeof(unative_t); |
| 375 | 364 | ||
| 376 | return 0; |
365 | return 0; |
| 377 | } |
366 | } |
| Line 490... | Line 479... | ||
| 490 | int udebug_mem_read(unative_t uspace_addr, size_t n, void **buffer) |
479 | int udebug_mem_read(unative_t uspace_addr, size_t n, void **buffer) |
| 491 | { |
480 | { |
| 492 | void *data_buffer; |
481 | void *data_buffer; |
| 493 | int rc; |
482 | int rc; |
| 494 | 483 | ||
| - | 484 | /* Verify task state */ |
|
| 495 | klog_printf("udebug_mem_read()"); |
485 | mutex_lock(&TASK->udebug.lock); |
| - | 486 | ||
| - | 487 | if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) { |
|
| - | 488 | mutex_unlock(&TASK->udebug.lock); |
|
| - | 489 | return EBUSY; |
|
| - | 490 | } |
|
| 496 | 491 | ||
| 497 | data_buffer = malloc(n, 0); |
492 | data_buffer = malloc(n, 0); |
| 498 | 493 | ||
| 499 | klog_printf("udebug_mem_read: src=%u, size=%u", uspace_addr, n); |
494 | // klog_printf("udebug_mem_read: src=%u, size=%u", uspace_addr, n); |
| 500 | 495 | ||
| 501 | /* NOTE: this is not strictly from a syscall... but that shouldn't |
496 | /* NOTE: this is not strictly from a syscall... but that shouldn't |
| 502 | * be a problem */ |
497 | * be a problem */ |
| 503 | rc = copy_from_uspace(data_buffer, (void *)uspace_addr, n); |
498 | rc = copy_from_uspace(data_buffer, (void *)uspace_addr, n); |
| - | 499 | mutex_unlock(&TASK->udebug.lock); |
|
| - | 500 | ||
| 504 | if (rc) return rc; |
501 | if (rc != 0) return rc; |
| 505 | 502 | ||
| 506 | *buffer = data_buffer; |
503 | *buffer = data_buffer; |
| 507 | return 0; |
504 | return 0; |
| 508 | } |
505 | } |
| 509 | 506 | ||
| 510 | int udebug_mem_write(unative_t uspace_addr, void *data, size_t n) |
507 | int udebug_mem_write(unative_t uspace_addr, void *data, size_t n) |
| 511 | { |
508 | { |
| 512 | int rc; |
509 | int rc; |
| 513 | udebug_task_state_t dts; |
- | |
| 514 | 510 | ||
| 515 | klog_printf("udebug_mem_write()"); |
511 | klog_printf("udebug_mem_write()"); |
| 516 | 512 | ||
| 517 | /* Verify task state */ |
513 | /* Verify task state */ |
| 518 | spinlock_lock(&TASK->lock); |
514 | mutex_lock(&TASK->udebug.lock); |
| 519 | dts = TASK->udebug.dt_state; |
- | |
| 520 | spinlock_unlock(&TASK->lock); |
- | |
| 521 | 515 | ||
| 522 | if (dts != UDEBUG_TS_ACTIVE) |
516 | if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) { |
| - | 517 | mutex_unlock(&TASK->udebug.lock); |
|
| 523 | return EBUSY; |
518 | return EBUSY; |
| - | 519 | } |
|
| 524 | 520 | ||
| 525 | klog_printf("dst=%u, size=%u", uspace_addr, n); |
521 | klog_printf("dst=%u, size=%u", uspace_addr, n); |
| 526 | 522 | ||
| 527 | /* NOTE: this is not strictly from a syscall... but that shouldn't |
523 | /* NOTE: this is not strictly from a syscall... but that shouldn't |
| 528 | * be a problem */ |
524 | * be a problem */ |
| 529 | // rc = copy_to_uspace((void *)uspace_addr, data, n); |
525 | // rc = copy_to_uspace((void *)uspace_addr, data, n); |
| 530 | // if (rc) return rc; |
526 | // if (rc) return rc; |
| 531 | 527 | ||
| 532 | rc = as_debug_write(uspace_addr, data, n); |
528 | rc = as_debug_write(uspace_addr, data, n); |
| 533 | 529 | ||
| - | 530 | mutex_unlock(&TASK->udebug.lock); |
|
| - | 531 | ||
| 534 | return rc; |
532 | return rc; |
| 535 | } |
533 | } |
| 536 | 534 | ||
| 537 | /** @} |
535 | /** @} |
| 538 | */ |
536 | */ |