Subversion Repositories HelenOS

Rev

Rev 2819 | Rev 2824 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2819 Rev 2823
Line 15... Line 15...
15
#include <ipc/ipc.h>
15
#include <ipc/ipc.h>
16
#include <syscall/copy.h>
16
#include <syscall/copy.h>
17
#include <udebug/udebug.h>
17
#include <udebug/udebug.h>
18
#include <udebug/udebug_ipc.h>
18
#include <udebug/udebug_ipc.h>
19
 
19
 
-
 
20
/**
-
 
21
 * Get and lock a phone's callee task.
-
 
22
 *
-
 
23
 * This will return a pointer to the task to which the phone
-
 
24
 * is connected. It will lock the task, making sure it exists.
-
 
25
 * (TODO: make sure the udebug-cleanup of the task hasn't
-
 
26
 * started yet)
-
 
27
 */
20
static task_t *get_lock_callee_task(phone_t *phone)
28
static task_t *get_lock_callee_task(phone_t *phone)
21
{
29
{
22
    answerbox_t *answerbox;
30
    answerbox_t *box;
23
    task_t *ta;
31
    task_t *ta;
-
 
32
    task_id_t taskid;
-
 
33
    ipl_t ipl;
24
 
34
 
-
 
35
    ipl = interrupts_disable();
25
    // FIXME: locking!!!
36
    spinlock_lock(&phone->lock);
-
 
37
    if (phone->state != IPC_PHONE_CONNECTED) {
-
 
38
        spinlock_unlock(&phone->lock);
-
 
39
        interrupts_restore(ipl);
-
 
40
        return NULL;
-
 
41
    }
26
 
42
 
27
    answerbox = phone->callee;
43
    box = phone->callee;
-
 
44
   
-
 
45
    spinlock_lock(&box->lock);
28
    ta = answerbox->task;
46
    ta = box->task;
-
 
47
    taskid = ta->taskid;
-
 
48
    spinlock_unlock(&box->lock);
-
 
49
    spinlock_unlock(&phone->lock);
-
 
50
 
-
 
51
    /* Locking decoupled using taskid */
-
 
52
   
-
 
53
    spinlock_lock(&tasks_lock);
-
 
54
    ta = task_find_by_id(taskid);
-
 
55
    if (ta == NULL) {
-
 
56
        spinlock_unlock(&tasks_lock);
-
 
57
        interrupts_restore(ipl);
-
 
58
        return NULL;
-
 
59
    }
29
 
60
 
30
    spinlock_lock(&ta->lock);
61
    spinlock_lock(&ta->lock);
-
 
62
    spinlock_unlock(&tasks_lock);
-
 
63
    interrupts_restore(ipl);
31
 
64
 
32
    return ta;
65
    return ta;
33
}
66
}
34
 
67
 
35
static int udebug_rp_begin(call_t *call, phone_t *phone)
68
static int udebug_rp_begin(call_t *call, phone_t *phone)
36
{
69
{
37
    task_t *ta;
70
    task_t *ta;
-
 
71
    ipl_t ipl;
38
 
72
 
39
    klog_printf("debug_begin()");
73
    klog_printf("debug_begin()");
40
 
74
 
-
 
75
    ipl = interrupts_disable();
41
    ta = get_lock_callee_task(phone);
76
    ta = get_lock_callee_task(phone);
42
    klog_printf("debugging task %llu", ta->taskid);
77
    klog_printf("debugging task %llu", ta->taskid);
43
 
78
 
44
    if (ta->being_debugged != false) {
79
    if (ta->being_debugged != false) {
45
        spinlock_unlock(&ta->lock);
80
        spinlock_unlock(&ta->lock);
-
 
81
        interrupts_restore(ipl);
46
        klog_printf("debug_begin(): busy error");
82
        klog_printf("debug_begin(): busy error");
47
        return EBUSY;
83
        return EBUSY;
48
    }
84
    }
49
 
85
 
50
    ta->being_debugged = true;
86
    ta->being_debugged = true;
Line 53... Line 89...
53
 
89
 
54
    if (ta->not_stoppable_count == 0) {
90
    if (ta->not_stoppable_count == 0) {
55
        ta->debug_begin_call = NULL;
91
        ta->debug_begin_call = NULL;
56
        ta->stop_request = false;
92
        ta->stop_request = false;
57
        spinlock_unlock(&ta->lock);
93
        spinlock_unlock(&ta->lock);
-
 
94
        interrupts_restore(ipl);
58
        klog_printf("debug_begin(): immediate backsend");
95
        klog_printf("debug_begin(): immediate backsend");
59
        return 1; /* actually we need backsend with 0 retval */
96
        return 1; /* actually we need backsend with 0 retval */
60
    }
97
    }
61
 
98
 
62
    spinlock_unlock(&ta->lock);
99
    spinlock_unlock(&ta->lock);
-
 
100
    interrupts_restore(ipl);
63
 
101
 
64
    klog_printf("debug_begin() done (wait for stoppability)");
102
    klog_printf("debug_begin() done (wait for stoppability)");
65
    return 0;
103
    return 0;
66
}
104
}
67
 
105
 
68
static int udebug_rp_go(call_t *call, phone_t *phone)
106
static int udebug_rp_go(call_t *call, phone_t *phone)
69
{
107
{
70
    thread_t *t;
108
    thread_t *t;
71
    task_t *ta;
109
    task_t *ta;
-
 
110
    ipl_t ipl;
72
 
111
 
73
    klog_printf("debug_go()");
112
    klog_printf("debug_go()");
74
    ta = get_lock_callee_task(phone);
113
    ta = get_lock_callee_task(phone);
75
 
114
 
76
    // FIXME: must save this in thread struct, not task struct!!!
115
    // FIXME: must save this in thread struct, not task struct!!!
77
    ta->debug_go_call = call;
116
    ta->debug_go_call = call;
-
 
117
    spinlock_unlock(&ta->lock);
-
 
118
 
78
    t = (thread_t *) IPC_GET_ARG2(call->data);
119
    t = (thread_t *) IPC_GET_ARG2(call->data);
-
 
120
 
-
 
121
    ipl = interrupts_disable();
-
 
122
    spinlock_lock(&threads_lock);
79
    if (!thread_exists(t)) {
123
    if (!thread_exists(t)) {
80
        spinlock_unlock(&ta->lock);
124
        spinlock_unlock(&threads_lock);
-
 
125
        interrupts_restore(ipl);
81
        return ENOENT;
126
        return ENOENT;
82
    }
127
    }
83
 
128
 
84
    klog_printf("debug_go(): waitq_wakeup");
-
 
85
    waitq_wakeup(&t->go_wq, WAKEUP_FIRST);
129
    waitq_wakeup(&t->go_wq, WAKEUP_FIRST);
86
 
-
 
87
    spinlock_unlock(&ta->lock);
130
    spinlock_unlock(&threads_lock);
-
 
131
    interrupts_restore(ipl);
88
 
132
 
89
    return 0; /* no backsend */
133
    return 0; /* no backsend */
90
}
134
}
91
 
135
 
92
static int udebug_rp_args_read(call_t *call, phone_t *phone)
136
static int udebug_rp_args_read(call_t *call, phone_t *phone)
Line 94... Line 138...
94
    thread_t *t;
138
    thread_t *t;
95
    task_t *ta;
139
    task_t *ta;
96
    void *uspace_buffer;
140
    void *uspace_buffer;
97
    unative_t to_copy;
141
    unative_t to_copy;
98
    int rc;
142
    int rc;
-
 
143
    ipl_t ipl;
99
 
144
 
100
    klog_printf("debug_args_read()");
145
    klog_printf("debug_args_read()");
101
    // FIXME: verify task/thread state
146
    // FIXME: verify task/thread state
102
 
147
 
103
    ta = get_lock_callee_task(phone);
148
    ta = get_lock_callee_task(phone);
104
    klog_printf("task %llu", ta->taskid);
149
    klog_printf("task %llu", ta->taskid);
-
 
150
    spinlock_unlock(&ta->lock);
-
 
151
 
105
    t = (thread_t *) IPC_GET_ARG2(call->data);
152
    t = (thread_t *) IPC_GET_ARG2(call->data);
-
 
153
 
-
 
154
    ipl = interrupts_disable();
-
 
155
    spinlock_lock(&threads_lock);
-
 
156
 
106
    if (!thread_exists(t)) {
157
    if (!thread_exists(t)) {
107
        spinlock_unlock(&ta->lock);
158
        spinlock_unlock(&threads_lock);
-
 
159
        interrupts_restore(ipl);
108
        return ENOENT;
160
        return ENOENT;
109
    }
161
    }
110
 
162
 
-
 
163
    // FIXME: copy to a local buffer before releasing the lock
-
 
164
    spinlock_unlock(&threads_lock);
-
 
165
    interrupts_restore(ipl);
-
 
166
 
111
    uspace_buffer = (void *)IPC_GET_ARG3(call->data);
167
    uspace_buffer = (void *)IPC_GET_ARG3(call->data);
112
    to_copy = IPC_GET_ARG4(call->data);
168
    to_copy = IPC_GET_ARG4(call->data);
113
    if (to_copy > 6 * sizeof(unative_t)) to_copy = 6 * sizeof(unative_t);
169
    if (to_copy > 6 * sizeof(unative_t)) to_copy = 6 * sizeof(unative_t);
114
 
170
 
115
    rc = copy_to_uspace(uspace_buffer, t->syscall_args, to_copy);
171
    rc = copy_to_uspace(uspace_buffer, t->syscall_args, to_copy);
Line 117... Line 173...
117
        spinlock_unlock(&ta->lock);
173
        spinlock_unlock(&ta->lock);
118
        klog_printf("debug_args_read() - copy failed");
174
        klog_printf("debug_args_read() - copy failed");
119
        return rc;
175
        return rc;
120
    }
176
    }
121
 
177
 
122
    spinlock_unlock(&ta->lock);
-
 
123
 
-
 
124
    IPC_SET_ARG1(call->data, to_copy);
178
    IPC_SET_ARG1(call->data, to_copy);
125
 
179
 
126
    klog_printf("debug_args_read() done");
180
    klog_printf("debug_args_read() done");
127
    return 1; /* actually need becksend with retval 0 */
181
    return 1; /* actually need becksend with retval 0 */
128
}
182
}