Rev 2854 | Rev 2867 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2854 | Rev 2866 | ||
---|---|---|---|
1 | /** @addtogroup generic |
1 | /** @addtogroup generic |
2 | * @{ |
2 | * @{ |
3 | */ |
3 | */ |
4 | 4 | ||
5 | /** |
5 | /** |
6 | * @file |
6 | * @file |
7 | * @brief Tdebug. |
7 | * @brief Tdebug. |
8 | */ |
8 | */ |
9 | 9 | ||
10 | #include <synch/waitq.h> |
10 | #include <synch/waitq.h> |
11 | #include <console/klog.h> |
11 | #include <console/klog.h> |
12 | #include <udebug/udebug.h> |
12 | #include <udebug/udebug.h> |
13 | #include <arch.h> |
13 | #include <arch.h> |
14 | 14 | ||
15 | void udebug_stoppable_begin(void) |
15 | void udebug_stoppable_begin(void) |
16 | { |
16 | { |
17 | int nsc; |
17 | int nsc; |
18 | call_t *db_call; |
18 | call_t *db_call; |
19 | ipl_t ipl; |
19 | ipl_t ipl; |
20 | 20 | ||
21 | ipl = interrupts_disable(); |
21 | ipl = interrupts_disable(); |
22 | spinlock_lock(&TASK->lock); |
22 | spinlock_lock(&TASK->lock); |
23 | 23 | ||
24 | nsc = --TASK->not_stoppable_count; |
24 | nsc = --TASK->not_stoppable_count; |
25 | db_call = TASK->debug_begin_call; |
25 | db_call = TASK->debug_begin_call; |
26 | 26 | ||
27 | if (TASK->dt_state == UDEBUG_TS_BEGINNING) { |
27 | if (TASK->dt_state == UDEBUG_TS_BEGINNING) { |
28 | klog_printf("udebug_stoppable_begin"); |
28 | klog_printf("udebug_stoppable_begin"); |
29 | klog_printf(" - nsc := %d", nsc); |
29 | klog_printf(" - nsc := %d", nsc); |
30 | } |
30 | } |
31 | 31 | ||
32 | if (TASK->dt_state == UDEBUG_TS_BEGINNING && nsc == 0) { |
32 | if (TASK->dt_state == UDEBUG_TS_BEGINNING && nsc == 0) { |
33 | TASK->dt_state = UDEBUG_TS_ACTIVE; |
33 | TASK->dt_state = UDEBUG_TS_ACTIVE; |
34 | TASK->debug_begin_call = NULL; |
34 | TASK->debug_begin_call = NULL; |
35 | spinlock_unlock(&TASK->lock); |
35 | spinlock_unlock(&TASK->lock); |
36 | interrupts_restore(ipl); |
36 | interrupts_restore(ipl); |
37 | 37 | ||
38 | IPC_SET_RETVAL(db_call->data, 0); |
38 | IPC_SET_RETVAL(db_call->data, 0); |
39 | klog_printf("udebug_stoppable_begin/ipc_answer"); |
39 | klog_printf("udebug_stoppable_begin/ipc_answer"); |
40 | ipc_answer(&TASK->answerbox, db_call); |
40 | ipc_answer(&TASK->answerbox, db_call); |
41 | } else { |
41 | } else { |
42 | spinlock_unlock(&TASK->lock); |
42 | spinlock_unlock(&TASK->lock); |
43 | interrupts_restore(ipl); |
43 | interrupts_restore(ipl); |
44 | } |
44 | } |
45 | } |
45 | } |
46 | 46 | ||
47 | void udebug_stoppable_end(void) |
47 | void udebug_stoppable_end(void) |
48 | { |
48 | { |
49 | ipl_t ipl; |
49 | ipl_t ipl; |
50 | 50 | ||
51 | restart: |
51 | restart: |
52 | ipl = interrupts_disable(); |
52 | ipl = interrupts_disable(); |
53 | spinlock_lock(&TASK->lock); |
53 | spinlock_lock(&TASK->lock); |
54 | 54 | ||
55 | if ((TASK->dt_state == UDEBUG_TS_BEGINNING || |
55 | if ((TASK->dt_state == UDEBUG_TS_BEGINNING || |
56 | TASK->dt_state == UDEBUG_TS_ACTIVE) && |
56 | TASK->dt_state == UDEBUG_TS_ACTIVE) && |
57 | THREAD->debug_stop == true) { |
57 | THREAD->debug_stop == true) { |
58 | TASK->debug_begin_call = NULL; |
58 | TASK->debug_begin_call = NULL; |
59 | spinlock_unlock(&TASK->lock); |
59 | spinlock_unlock(&TASK->lock); |
60 | interrupts_restore(ipl); |
60 | interrupts_restore(ipl); |
61 | 61 | ||
62 | klog_printf("udebug_stoppable_end: waitq_sleep"); |
62 | klog_printf("udebug_stoppable_end: waitq_sleep"); |
63 | waitq_sleep(&THREAD->go_wq); |
63 | waitq_sleep(&THREAD->go_wq); |
64 | goto restart; |
64 | goto restart; |
65 | /* must try again - have to lose stoppability atomically */ |
65 | /* must try again - have to lose stoppability atomically */ |
66 | } else { |
66 | } else { |
67 | ++TASK->not_stoppable_count; |
67 | ++TASK->not_stoppable_count; |
68 | spinlock_unlock(&TASK->lock); |
68 | spinlock_unlock(&TASK->lock); |
69 | interrupts_restore(ipl); |
69 | interrupts_restore(ipl); |
70 | } |
70 | } |
71 | } |
71 | } |
72 | 72 | ||
73 | void udebug_syscall_event(unative_t a1, unative_t a2, unative_t a3, |
73 | void udebug_syscall_event(unative_t a1, unative_t a2, unative_t a3, |
74 | unative_t a4, unative_t a5, unative_t a6, unative_t id, unative_t rc) |
74 | unative_t a4, unative_t a5, unative_t a6, unative_t id, unative_t rc) |
75 | { |
75 | { |
76 | call_t *call; |
76 | call_t *call; |
77 | ipl_t ipl; |
77 | ipl_t ipl; |
78 | 78 | ||
79 | ipl = interrupts_disable(); |
79 | ipl = interrupts_disable(); |
80 | spinlock_lock(&THREAD->debug_lock); |
80 | spinlock_lock(&THREAD->debug_lock); |
81 | 81 | ||
82 | /* Must only generate events when in debugging session and have go */ |
82 | /* Must only generate events when in debugging session and have go */ |
83 | if (THREAD->debug_active == true && |
83 | if (THREAD->debug_active == true && |
84 | THREAD->debug_stop == false) { |
84 | THREAD->debug_stop == false) { |
85 | klog_printf("udebug_syscall_event"); |
85 | klog_printf("udebug_syscall_event"); |
86 | call = THREAD->debug_go_call; |
86 | call = THREAD->debug_go_call; |
87 | IPC_SET_RETVAL(call->data, 0); |
87 | IPC_SET_RETVAL(call->data, 0); |
88 | IPC_SET_ARG1(call->data, UDEBUG_EVENT_SYSCALL); |
88 | IPC_SET_ARG1(call->data, UDEBUG_EVENT_SYSCALL); |
89 | IPC_SET_ARG2(call->data, id); |
89 | IPC_SET_ARG2(call->data, id); |
90 | IPC_SET_ARG3(call->data, rc); |
90 | IPC_SET_ARG3(call->data, rc); |
91 | klog_printf("udebug_syscall_event/ipc_answer"); |
91 | klog_printf("udebug_syscall_event/ipc_answer"); |
92 | 92 | ||
93 | THREAD->syscall_args[0] = a1; |
93 | THREAD->syscall_args[0] = a1; |
94 | THREAD->syscall_args[1] = a2; |
94 | THREAD->syscall_args[1] = a2; |
95 | THREAD->syscall_args[2] = a3; |
95 | THREAD->syscall_args[2] = a3; |
96 | THREAD->syscall_args[3] = a4; |
96 | THREAD->syscall_args[3] = a4; |
97 | THREAD->syscall_args[4] = a5; |
97 | THREAD->syscall_args[4] = a5; |
98 | THREAD->syscall_args[5] = a6; |
98 | THREAD->syscall_args[5] = a6; |
99 | 99 | ||
100 | /* |
100 | /* |
101 | * Make sure debug_stop is true when going to sleep |
101 | * Make sure debug_stop is true when going to sleep |
102 | * in case we get woken up by DEBUG_END. (At which |
102 | * in case we get woken up by DEBUG_END. (At which |
103 | * point it must be back to the initial true value). |
103 | * point it must be back to the initial true value). |
104 | */ |
104 | */ |
105 | THREAD->debug_stop = true; |
105 | THREAD->debug_stop = true; |
- | 106 | ||
- | 107 | THREAD->cur_event = UDEBUG_EVENT_SYSCALL; |
|
106 | spinlock_unlock(&THREAD->debug_lock); |
108 | spinlock_unlock(&THREAD->debug_lock); |
107 | 109 | ||
108 | spinlock_lock(&TASK->lock); |
110 | spinlock_lock(&TASK->lock); |
109 | ipc_answer(&TASK->answerbox, THREAD->debug_go_call); |
111 | ipc_answer(&TASK->answerbox, THREAD->debug_go_call); |
110 | spinlock_unlock(&TASK->lock); |
112 | spinlock_unlock(&TASK->lock); |
111 | 113 | ||
112 | interrupts_restore(ipl); |
114 | interrupts_restore(ipl); |
113 | 115 | ||
114 | waitq_sleep(&THREAD->go_wq); |
116 | waitq_sleep(&THREAD->go_wq); |
115 | } else { |
117 | } else { |
116 | spinlock_unlock(&THREAD->debug_lock); |
118 | spinlock_unlock(&THREAD->debug_lock); |
117 | interrupts_restore(ipl); |
119 | interrupts_restore(ipl); |
118 | } |
120 | } |
119 | } |
121 | } |
120 | 122 | ||
121 | /** @} |
123 | /** @} |
122 | */ |
124 | */ |
123 | 125 |