Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2823 → Rev 2824

/branches/tracing/kernel/generic/src/udebug/udebug_ipc.c
189,28 → 189,41
unative_t to_copy;
int rc;
istate_t *state;
istate_t state_copy;
ipl_t ipl;
 
klog_printf("debug_regs_read()");
// FIXME: verify task/thread state
 
state = THREAD->uspace_state;
if (state == NULL) {
klog_printf("debug_regs_read() - istate not available");
return EBUSY;
}
ta = get_lock_callee_task(phone);
spinlock_unlock(&ta->lock);
 
ta = get_lock_callee_task(phone);
ipl = interrupts_disable();
spinlock_lock(&threads_lock);
 
t = (thread_t *) IPC_GET_ARG2(call->data);
if (!thread_exists(t)) {
spinlock_unlock(&ta->lock);
return ENOENT;
}
 
state = t->uspace_state;
if (state == NULL) {
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
klog_printf("debug_regs_read() - istate not available");
return EBUSY;
}
 
/* Copy to a local buffer so that we can release the lock */
memcpy(&state_copy, state, sizeof(state_copy));
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
 
uspace_buffer = (void *)IPC_GET_ARG3(call->data);
to_copy = IPC_GET_ARG4(call->data);
if (to_copy > sizeof(istate_t)) to_copy = sizeof(istate_t);
 
rc = copy_to_uspace(uspace_buffer, t->uspace_state, to_copy);
rc = copy_to_uspace(uspace_buffer, &state_copy, to_copy);
if (rc != 0) {
spinlock_unlock(&ta->lock);
klog_printf("debug_regs_read() - copy failed");
217,8 → 230,6
return rc;
}
 
spinlock_unlock(&ta->lock);
 
IPC_SET_ARG1(call->data, to_copy);
IPC_SET_ARG2(call->data, sizeof(istate_t));
 
234,36 → 245,55
unative_t to_copy;
int rc;
istate_t *state;
istate_t data_copy;
ipl_t ipl;
 
klog_printf("debug_regs_write()");
// FIXME: verify task/thread state
 
state = THREAD->uspace_state;
if (state == NULL) {
klog_printf("debug_regs_write() - istate not available");
return EBUSY;
}
/* First copy to a local buffer */
 
ta = get_lock_callee_task(phone);
t = (thread_t *) IPC_GET_ARG2(call->data);
if (!thread_exists(t)) {
spinlock_unlock(&ta->lock);
return ENOENT;
}
 
uspace_data = (void *)IPC_GET_ARG3(call->data);
to_copy = IPC_GET_ARG4(call->data);
if (to_copy > sizeof(istate_t)) to_copy = sizeof(istate_t);
 
rc = copy_from_uspace(t->uspace_state, uspace_data, to_copy);
rc = copy_from_uspace(&data_copy, uspace_data, to_copy);
if (rc != 0) {
spinlock_unlock(&ta->lock);
klog_printf("debug_regs_write() - copy failed");
return rc;
}
 
// FIXME: verify task/thread state
 
ta = get_lock_callee_task(phone);
spinlock_unlock(&ta->lock);
 
/* Now try to change the thread's uspace_state */
 
ipl = interrupts_disable();
spinlock_lock(&threads_lock);
 
t = (thread_t *) IPC_GET_ARG2(call->data);
if (!thread_exists(t)) {
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return ENOENT;
}
 
state = t->uspace_state;
if (state == NULL) {
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
klog_printf("debug_regs_write() - istate not available");
return EBUSY;
}
 
memcpy(t->uspace_state, &data_copy, sizeof(t->uspace_state));
 
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
 
/* Set answer values */
 
IPC_SET_ARG1(call->data, to_copy);
IPC_SET_ARG2(call->data, sizeof(istate_t));
 
279,53 → 309,73
unative_t *uspace_buffer;
unative_t to_copy;
int rc;
unsigned copied, total;
unsigned total_bytes;
unsigned buf_size;
unative_t tid;
unsigned num_threads, copied_ids;
ipl_t ipl;
unative_t *buffer;
int flags;
 
klog_printf("debug_thread_read()");
// FIXME: verify task/thread state
 
ipl = interrupts_disable();
ta = get_lock_callee_task(phone);
klog_printf("task %llu", ta->taskid);
uspace_buffer = (void *)IPC_GET_ARG2(call->data);
buf_size = IPC_GET_ARG3(call->data);
 
copied = total = 0;
/* Count the threads first */
 
num_threads = 0;
for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
/* Count all threads, to be on the safe side */
++num_threads;
}
 
/* Allocate a buffer and copy down the threads' ids */
buffer = malloc(num_threads * sizeof(unative_t), 0); // ???
 
copied_ids = 0;
for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
t = list_get_instance(cur, thread_t, th_link);
 
spinlock_lock(&t->lock);
flags = t->flags;
spinlock_unlock(&t->lock);
 
/* Not interested in kernel threads */
if ((t->flags & THREAD_FLAG_USPACE) == 0)
continue;
if ((flags & THREAD_FLAG_USPACE) != 0) {
/* Using thread struct pointer for identification */
tid = (unative_t) t;
buffer[copied_ids++] = tid;
}
}
 
/* Using thread struct pointer for identification */
tid = (unative_t) t;
spinlock_unlock(&ta->lock);
interrupts_restore(ipl);
 
to_copy = sizeof(unative_t);
if (copied + to_copy >= buf_size)
to_copy = buf_size - copied;
/* Now copy to userspace */
 
if (to_copy > 0) {
rc = copy_to_uspace(uspace_buffer, &tid, to_copy);
if (rc != 0) {
spinlock_unlock(&ta->lock);
klog_printf("debug_thread_read() - copy failed");
return rc;
}
}
uspace_buffer = (void *)IPC_GET_ARG2(call->data);
buf_size = IPC_GET_ARG3(call->data);
 
++uspace_buffer;
total += sizeof(unative_t);
copied += to_copy;
total_bytes = copied_ids * sizeof(unative_t);
 
if (buf_size > total_bytes)
to_copy = total_bytes;
else
to_copy = buf_size;
 
rc = copy_to_uspace(uspace_buffer, buffer, to_copy);
free(buffer);
 
if (rc != 0) {
klog_printf("debug_thread_read() - copy failed");
return rc;
}
 
spinlock_unlock(&ta->lock);
IPC_SET_ARG1(call->data, to_copy);
IPC_SET_ARG2(call->data, total_bytes);
 
IPC_SET_ARG1(call->data, copied);
IPC_SET_ARG2(call->data, total);
 
klog_printf("debug_thread_read() done");
return 1; /* actually need becksend with retval 0 */
}