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