Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3492 → Rev 3467

/branches/sparc/kernel/generic/src/udebug/udebug.c
File deleted
/branches/sparc/kernel/generic/src/udebug/udebug_ops.c
File deleted
/branches/sparc/kernel/generic/src/udebug/udebug_ipc.c
File deleted
/branches/sparc/kernel/generic/src/main/uinit.c
46,9 → 46,7
#include <userspace.h>
#include <mm/slab.h>
#include <arch.h>
#include <udebug/udebug.h>
 
 
/** Thread used to bring up userspace thread.
*
* @param arg Pointer to structure containing userspace entry and stack
67,10 → 65,6
* deployed for the event of forceful task termination.
*/
thread_detach(THREAD);
 
#ifdef CONFIG_UDEBUG
udebug_stoppable_end();
#endif
uarg.uspace_entry = ((uspace_arg_t *) arg)->uspace_entry;
uarg.uspace_stack = ((uspace_arg_t *) arg)->uspace_stack;
/branches/sparc/kernel/generic/src/proc/task.c
155,18 → 155,7
 
ta->capabilities = 0;
ta->cycles = 0;
 
#ifdef CONFIG_UDEBUG
/* Init debugging stuff */
udebug_task_init(&ta->udebug);
 
/* Init kbox stuff */
ipc_answerbox_init(&ta->kernel_box, ta);
ta->kb_thread = NULL;
mutex_initialize(&ta->kb_cleanup_lock, MUTEX_PASSIVE);
ta->kb_finished = false;
#endif
 
ipc_answerbox_init(&ta->answerbox, ta);
for (i = 0; i < IPC_MAX_PHONES; i++)
ipc_phone_init(&ta->phones[i]);
/branches/sparc/kernel/generic/src/proc/thread.c
180,10 → 180,6
return -1;
}
 
#ifdef CONFIG_UDEBUG
mutex_initialize(&t->udebug.lock, MUTEX_PASSIVE);
#endif
 
return 0;
}
 
351,11 → 347,6
avltree_node_initialize(&t->threads_tree_node);
t->threads_tree_node.key = (uintptr_t) t;
 
#ifdef CONFIG_UDEBUG
/* Init debugging stuff */
udebug_thread_initialize(&t->udebug);
#endif
 
/* might depend on previous initialization */
thread_create_arch(t);
 
418,17 → 409,12
ipl_t ipl;
 
/*
* Attach to the specified task.
* Attach to the current task.
*/
ipl = interrupts_disable();
spinlock_lock(&task->lock);
 
atomic_inc(&task->refcount);
 
/* Must not count kbox thread into lifecount */
if (t->flags & THREAD_FLAG_USPACE)
atomic_inc(&task->lifecount);
 
atomic_inc(&task->lifecount);
list_append(&t->th_link, &task->th_head);
spinlock_unlock(&task->lock);
 
451,19 → 437,14
{
ipl_t ipl;
 
if (THREAD->flags & THREAD_FLAG_USPACE) {
#ifdef CONFIG_UDEBUG
/* Generate udebug THREAD_E event */
udebug_thread_e_event();
#endif
if (atomic_predec(&TASK->lifecount) == 0) {
/*
* We are the last userspace thread in the task that
* still has not exited. With the exception of the
* moment the task was created, new userspace threads
* can only be created by threads of the same task.
* We are safe to perform cleanup.
*/
if (atomic_predec(&TASK->lifecount) == 0) {
/*
* We are the last thread in the task that still has not exited.
* With the exception of the moment the task was created, new
* threads can only be created by threads of the same task.
* We are safe to perform cleanup.
*/
if (THREAD->flags & THREAD_FLAG_USPACE) {
ipc_cleanup();
futex_cleanup();
LOG("Cleanup of task %" PRIu64" completed.", TASK->taskid);
760,11 → 741,6
thread_attach(t, TASK);
thread_ready(t);
 
#ifdef CONFIG_UDEBUG
/* Generate udebug THREAD_B event */
udebug_thread_b_event(t);
#endif
 
return 0;
} else
free(kernel_uarg);
/branches/sparc/kernel/generic/src/mm/as.c
385,7 → 385,7
if (pages < area->pages) {
bool cond;
uintptr_t start_free = area->base + pages * PAGE_SIZE;
uintptr_t start_free = area->base + pages*PAGE_SIZE;
 
/*
* Shrinking the area.
395,7 → 395,7
/*
* Start TLB shootdown sequence.
*/
tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base +
tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base +
pages * PAGE_SIZE, area->pages - pages);
 
/*
/branches/sparc/kernel/generic/src/ipc/kbox.c
File deleted
/branches/sparc/kernel/generic/src/ipc/sysipc.c
42,9 → 42,8
#include <ipc/sysipc.h>
#include <ipc/irq.h>
#include <ipc/ipcrsc.h>
#include <ipc/kbox.h>
#include <udebug/udebug_ipc.h>
#include <arch/interrupt.h>
#include <print.h>
#include <syscall/copy.h>
#include <security/cap.h>
#include <mm/as.h>
296,11 → 295,10
/** Called before the request is sent.
*
* @param call Call structure with the request.
* @param phone Phone that the call will be sent through.
*
* @return Return 0 on success, ELIMIT or EPERM on error.
*/
static int request_preprocess(call_t *call, phone_t *phone)
static int request_preprocess(call_t *call)
{
int newphid;
size_t size;
342,10 → 340,6
return rc;
}
break;
#ifdef CONFIG_UDEBUG
case IPC_M_DEBUG_ALL:
return udebug_request_preprocess(call, phone);
#endif
default:
break;
}
375,7 → 369,6
 
if (call->buffer) {
/* This must be an affirmative answer to IPC_M_DATA_READ. */
/* or IPC_M_DEBUG_ALL/UDEBUG_M_MEM_READ... */
uintptr_t dst = IPC_GET_ARG1(call->data);
size_t size = IPC_GET_ARG2(call->data);
int rc = copy_to_uspace((void *) dst, call->buffer, size);
406,13 → 399,7
return -1;
}
IPC_SET_ARG5(call->data, phoneid);
}
switch (IPC_GET_METHOD(call->data)) {
case IPC_M_DEBUG_ALL:
return -1;
default:
break;
}
}
return 0;
}
 
454,7 → 441,7
IPC_SET_ARG4(call.data, 0);
IPC_SET_ARG5(call.data, 0);
 
if (!(res = request_preprocess(&call, phone))) {
if (!(res = request_preprocess(&call))) {
rc = ipc_call_sync(phone, &call);
if (rc != EOK)
return rc;
494,7 → 481,7
 
GET_CHECK_PHONE(phone, phoneid, return ENOENT);
 
if (!(res = request_preprocess(&call, phone))) {
if (!(res = request_preprocess(&call))) {
rc = ipc_call_sync(phone, &call);
if (rc != EOK)
return rc;
563,7 → 550,7
*/
IPC_SET_ARG5(call->data, 0);
 
if (!(res = request_preprocess(call, phone)))
if (!(res = request_preprocess(call)))
ipc_call(phone, call);
else
ipc_backsend_err(phone, call, res);
597,7 → 584,7
ipc_call_free(call);
return (unative_t) rc;
}
if (!(res = request_preprocess(call, phone)))
if (!(res = request_preprocess(call)))
ipc_call(phone, call);
else
ipc_backsend_err(phone, call, res);
822,16 → 809,11
 
ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
 
atomic_dec(&TASK->active_calls);
 
if (call->flags & IPC_CALL_DISCARD_ANSWER) {
ipc_call_free(call);
goto restart;
} else {
/*
* Decrement the counter of active calls only if the
* call is not an answer to IPC_M_PHONE_HUNGUP,
* which doesn't contribute to the counter.
*/
atomic_dec(&TASK->active_calls);
}
 
STRUCT_TO_USPACE(&calldata->args, &call->data.args);
886,30 → 868,5
return 0;
}
 
#include <console/console.h>
 
/**
* Syscall connect to a task by id.
*
* @return Phone id on success, or negative error code.
*/
unative_t sys_ipc_connect_kbox(sysarg64_t *uspace_taskid_arg)
{
#ifdef CONFIG_UDEBUG
sysarg64_t taskid_arg;
int rc;
rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
if (rc != 0)
return (unative_t) rc;
 
LOG("sys_ipc_connect_kbox(%" PRIu64 ")\n", taskid_arg.value);
 
return ipc_connect_kbox(taskid_arg.value);
#else
return (unative_t) ENOTSUP;
#endif
}
 
/** @}
*/
/branches/sparc/kernel/generic/src/ipc/ipc.c
43,7 → 43,6
#include <synch/waitq.h>
#include <synch/synch.h>
#include <ipc/ipc.h>
#include <ipc/kbox.h>
#include <errno.h>
#include <mm/slab.h>
#include <arch.h>
52,7 → 51,6
#include <debug.h>
 
#include <print.h>
#include <console/console.h>
#include <proc/thread.h>
#include <arch/interrupt.h>
#include <ipc/irq.h>
429,7 → 427,7
*
* @param lst Head of the list to be cleaned up.
*/
void ipc_cleanup_call_list(link_t *lst)
static void ipc_cleanup_call_list(link_t *lst)
{
call_t *call;
 
444,31 → 442,33
}
}
 
/** Disconnects all phones connected to an answerbox.
/** Cleans up all IPC communication of the current task.
*
* @param box Answerbox to disconnect phones from.
* @param notify_box If true, the answerbox will get a hangup message for
* each disconnected phone.
* Note: ipc_hangup sets returning answerbox to TASK->answerbox, you
* have to change it as well if you want to cleanup other tasks than TASK.
*/
void ipc_answerbox_slam_phones(answerbox_t *box, bool notify_box)
void ipc_cleanup(void)
{
int i;
call_t *call;
phone_t *phone;
DEADLOCK_PROBE_INIT(p_phonelck);
ipl_t ipl;
call_t *call;
 
call = notify_box ? ipc_call_alloc(0) : NULL;
/* Disconnect all our phones ('ipc_phone_hangup') */
for (i = 0; i < IPC_MAX_PHONES; i++)
ipc_phone_hangup(&TASK->phones[i]);
 
/* Disconnect all connected irqs */
ipc_irq_cleanup(&TASK->answerbox);
 
/* Disconnect all phones connected to our answerbox */
restart_phones:
ipl = interrupts_disable();
spinlock_lock(&box->lock);
while (!list_empty(&box->connected_phones)) {
phone = list_get_instance(box->connected_phones.next,
spinlock_lock(&TASK->answerbox.lock);
while (!list_empty(&TASK->answerbox.connected_phones)) {
phone = list_get_instance(TASK->answerbox.connected_phones.next,
phone_t, link);
if (SYNCH_FAILED(mutex_trylock(&phone->lock))) {
spinlock_unlock(&box->lock);
interrupts_restore(ipl);
spinlock_unlock(&TASK->answerbox.lock);
DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD);
goto restart_phones;
}
475,70 → 475,13
/* Disconnect phone */
ASSERT(phone->state == IPC_PHONE_CONNECTED);
 
phone->state = IPC_PHONE_SLAMMED;
list_remove(&phone->link);
phone->state = IPC_PHONE_SLAMMED;
 
if (notify_box) {
mutex_unlock(&phone->lock);
spinlock_unlock(&box->lock);
interrupts_restore(ipl);
 
/*
* Send one message to the answerbox for each
* phone. Used to make sure the kbox thread
* wakes up after the last phone has been
* disconnected.
*/
IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP);
call->flags |= IPC_CALL_DISCARD_ANSWER;
_ipc_call(phone, box, call);
 
/* Allocate another call in advance */
call = ipc_call_alloc(0);
 
/* Must start again */
goto restart_phones;
}
 
mutex_unlock(&phone->lock);
}
 
spinlock_unlock(&box->lock);
interrupts_restore(ipl);
 
/* Free unused call */
if (call)
ipc_call_free(call);
}
 
/** Cleans up all IPC communication of the current task.
*
* Note: ipc_hangup sets returning answerbox to TASK->answerbox, you
* have to change it as well if you want to cleanup other tasks than TASK.
*/
void ipc_cleanup(void)
{
int i;
call_t *call;
 
/* Disconnect all our phones ('ipc_phone_hangup') */
for (i = 0; i < IPC_MAX_PHONES; i++)
ipc_phone_hangup(&TASK->phones[i]);
 
/* Disconnect all connected irqs */
ipc_irq_cleanup(&TASK->answerbox);
 
/* Disconnect all phones connected to our regular answerbox */
ipc_answerbox_slam_phones(&TASK->answerbox, false);
 
#ifdef CONFIG_UDEBUG
/* Clean up kbox thread and communications */
ipc_kbox_cleanup();
#endif
 
/* Answer all messages in 'calls' and 'dispatched_calls' queues */
spinlock_lock(&TASK->answerbox.lock);
ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls);
ipc_cleanup_call_list(&TASK->answerbox.calls);
spinlock_unlock(&TASK->answerbox.lock);
574,13 → 517,7
(call->flags & IPC_CALL_NOTIF));
ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
/*
* Record the receipt of this call in the current task's counter
* of active calls. IPC_M_PHONE_HUNGUP calls do not contribute
* to this counter so do not record answers to them either.
*/
if (!(call->flags & IPC_CALL_DISCARD_ANSWER))
atomic_dec(&TASK->active_calls);
atomic_dec(&TASK->active_calls);
ipc_call_free(call);
}
}
/branches/sparc/kernel/generic/src/lib/memstr.c
34,10 → 34,12
* @file
* @brief Memory string operations.
*
* This file provides architecture independent functions to manipulate blocks of
* memory. These functions are optimized as much as generic functions of this
* type can be. However, architectures are free to provide even more optimized
* versions of these functions.
* This file provides architecture independent functions
* to manipulate blocks of memory. These functions
* are optimized as much as generic functions of
* this type can be. However, architectures are
* free to provide even more optimized versions of these
* functions.
*/
 
#include <memstr.h>
44,33 → 46,32
#include <arch/types.h>
#include <align.h>
 
/** Copy block of memory.
/** Copy block of memory
*
* Copy cnt bytes from src address to dst address. The copying is done
* word-by-word and then byte-by-byte. The source and destination memory areas
* cannot overlap.
* Copy cnt bytes from src address to dst address.
* The copying is done word-by-word and then byte-by-byte.
* The source and destination memory areas cannot overlap.
*
* @param src Source address to copy from.
* @param dst Destination address to copy to.
* @param cnt Number of bytes to copy.
* @param src Origin address to copy from.
* @param dst Origin address to copy to.
* @param cnt Number of bytes to copy.
*
* @return Destination address.
*/
void *_memcpy(void *dst, const void *src, size_t cnt)
void *_memcpy(void * dst, const void *src, size_t cnt)
{
unsigned int i, j;
if (ALIGN_UP((uintptr_t) src, sizeof(unative_t)) != (uintptr_t) src ||
ALIGN_UP((uintptr_t) dst, sizeof(unative_t)) != (uintptr_t) dst) {
ALIGN_UP((uintptr_t) dst, sizeof(unative_t)) != (uintptr_t) dst) {
for (i = 0; i < cnt; i++)
((uint8_t *) dst)[i] = ((uint8_t *) src)[i];
} else {
for (i = 0; i < cnt / sizeof(unative_t); i++)
((unative_t *) dst)[i] = ((unative_t *) src)[i];
for (j = 0; j < cnt % sizeof(unative_t); j++)
((uint8_t *)(((unative_t *) dst) + i))[j] =
((uint8_t *)(((unative_t *) src) + i))[j];
((uint8_t *)(((unative_t *) dst) + i))[j] = ((uint8_t *)(((unative_t *) src) + i))[j];
}
return (char *) dst;
78,12 → 79,12
 
/** Fill block of memory
*
* Fill cnt bytes at dst address with the value x. The filling is done
* byte-by-byte.
* Fill cnt bytes at dst address with the value x.
* The filling is done byte-by-byte.
*
* @param dst Destination address to fill.
* @param cnt Number of bytes to fill.
* @param x Value to fill.
* @param dst Origin address to fill.
* @param cnt Number of bytes to fill.
* @param x Value to fill.
*
*/
void _memsetb(void *dst, size_t cnt, uint8_t x)
95,14 → 96,14
p[i] = x;
}
 
/** Fill block of memory.
/** Fill block of memory
*
* Fill cnt words at dst address with the value x. The filling is done
* word-by-word.
* Fill cnt words at dst address with the value x.
* The filling is done word-by-word.
*
* @param dst Destination address to fill.
* @param cnt Number of words to fill.
* @param x Value to fill.
* @param dst Origin address to fill.
* @param cnt Number of words to fill.
* @param x Value to fill.
*
*/
void _memsetw(void *dst, size_t cnt, uint16_t x)
114,16 → 115,16
p[i] = x;
}
 
/** Copy string.
/** Copy string
*
* Copy string from src address to dst address. The copying is done
* char-by-char until the null character. The source and destination memory
* areas cannot overlap.
* Copy string from src address to dst address.
* The copying is done char-by-char until the null
* character. The source and destination memory areas
* cannot overlap.
*
* @param src Source string to copy from.
* @param dst Destination string to copy to.
* @param src Origin string to copy from.
* @param dst Origin string to copy to.
*
* @return Address of the destination string.
*/
char *strcpy(char *dest, const char *src)
{
/branches/sparc/kernel/generic/src/syscall/syscall.c
53,7 → 53,6
#include <syscall/copy.h>
#include <sysinfo/sysinfo.h>
#include <console/console.h>
#include <udebug/udebug.h>
 
/** Print using kernel facility
*
102,16 → 101,9
{
unative_t rc;
 
#ifdef CONFIG_UDEBUG
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false);
#endif
 
if (id < SYSCALL_END) {
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
#endif
if (id < SYSCALL_END)
rc = syscall_table[id](a1, a2, a3, a4, a5, a6);
} else {
else {
printf("Task %" PRIu64": Unknown syscall %#" PRIxn, TASK->taskid, id);
task_kill(TASK->taskid);
thread_exit();
119,11 → 111,6
if (THREAD->interrupted)
thread_exit();
 
#ifdef CONFIG_UDEBUG
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true);
udebug_stoppable_end();
#endif
return rc;
}
178,9 → 165,7
(syshandler_t) sys_sysinfo_value,
/* Debug calls */
(syshandler_t) sys_debug_enable_console,
 
(syshandler_t) sys_ipc_connect_kbox
(syshandler_t) sys_debug_enable_console
};
 
/** @}
/branches/sparc/kernel/generic/src/console/cmd.c
398,17 → 398,17
.argc = 0
};
 
/* Data and methods for 'ipc' command */
static int cmd_ipc(cmd_arg_t *argv);
static cmd_arg_t ipc_argv = {
/* Data and methods for 'ipc_task' command */
static int cmd_ipc_task(cmd_arg_t *argv);
static cmd_arg_t ipc_task_argv = {
.type = ARG_TYPE_INT,
};
static cmd_info_t ipc_info = {
.name = "ipc",
.description = "ipc <taskid> Show IPC information of given task.",
.func = cmd_ipc,
static cmd_info_t ipc_task_info = {
.name = "ipc_task",
.description = "ipc_task <taskid> Show IPC information of given task.",
.func = cmd_ipc_task,
.argc = 1,
.argv = &ipc_argv
.argv = &ipc_task_argv
};
 
/* Data and methods for 'zone' command */
461,7 → 461,7
&uptime_info,
&halt_info,
&help_info,
&ipc_info,
&ipc_task_info,
&set4_info,
&slabs_info,
&symaddr_info,
937,7 → 937,7
*
* return Always 1
*/
int cmd_ipc(cmd_arg_t * argv) {
int cmd_ipc_task(cmd_arg_t * argv) {
ipc_print_task(argv[0].intval);
return 1;
}
/branches/sparc/kernel/generic/include/udebug/udebug_ops.h
File deleted
/branches/sparc/kernel/generic/include/udebug/udebug_ipc.h
File deleted
/branches/sparc/kernel/generic/include/udebug/udebug.h
File deleted
/branches/sparc/kernel/generic/include/ipc/kbox.h
File deleted
/branches/sparc/kernel/generic/include/ipc/ipc.h
195,12 → 195,6
*/
#define IPC_M_DATA_READ 7
 
/** Debug the recipient.
* - ARG1 - specifies the debug method (from udebug_method_t)
* - other arguments are specific to the debug method
*/
#define IPC_M_DEBUG_ALL 8
 
/* Well-known methods */
#define IPC_M_LAST_SYSTEM 511
#define IPC_M_PING 512
313,8 → 307,6
extern int ipc_phone_hangup(phone_t *);
extern void ipc_backsend_err(phone_t *, call_t *, unative_t);
extern void ipc_print_task(task_id_t);
extern void ipc_answerbox_slam_phones(answerbox_t *, bool);
extern void ipc_cleanup_call_list(link_t *);
 
extern answerbox_t *ipc_phone_0;
 
/branches/sparc/kernel/generic/include/ipc/sysipc.h
57,7 → 57,6
unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method,
irq_code_t *ucode);
unative_t sys_ipc_unregister_irq(inr_t inr, devno_t devno);
unative_t sys_ipc_connect_kbox(sysarg64_t *task_id);
 
#endif
 
/branches/sparc/kernel/generic/include/proc/task.h
52,7 → 52,6
#include <arch/cpu.h>
#include <mm/tlb.h>
#include <proc/scheduler.h>
#include <udebug/udebug.h>
 
struct thread;
 
94,20 → 93,6
* certain extent.
*/
atomic_t active_calls;
 
#ifdef CONFIG_UDEBUG
/** Debugging stuff */
udebug_task_t udebug;
 
/** Kernel answerbox */
answerbox_t kernel_box;
/** Thread used to service kernel answerbox */
struct thread *kb_thread;
/** Kbox thread creation vs. begin of cleanup mutual exclusion */
mutex_t kb_cleanup_lock;
/** True if cleanup of kbox has already started */
bool kb_finished;
#endif
/** Architecture specific task data. */
task_arch_t arch;
/branches/sparc/kernel/generic/include/proc/thread.h
46,7 → 46,6
#include <arch/cpu.h>
#include <mm/tlb.h>
#include <proc/uarg.h>
#include <udebug/udebug.h>
 
#define THREAD_STACK_SIZE STACK_SIZE
#define THREAD_NAME_BUFLEN 20
204,12 → 203,6
 
/** Thread's kernel stack. */
uint8_t *kstack;
 
#ifdef CONFIG_UDEBUG
/** Debugging stuff */
udebug_thread_t udebug;
#endif
 
} thread_t;
 
/** Thread list lock.
/branches/sparc/kernel/generic/include/syscall/syscall.h
78,7 → 78,6
SYS_SYSINFO_VALUE,
SYS_DEBUG_ENABLE_CONSOLE,
SYS_IPC_CONNECT_KBOX,
SYSCALL_END
} syscall_t;