Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3430 → Rev 3431

/branches/tracing/kernel/kernel.config
144,6 → 144,8
# Virtually indexed D-cache support
! [ARCH=sparc64] CONFIG_VIRT_IDX_DCACHE (y/n)
 
# Support for userspace debuggers
! CONFIG_UDEBUG (y/n)
 
## Debugging configuration directives
 
/branches/tracing/kernel/generic/include/proc/task.h
95,6 → 95,7
*/
atomic_t active_calls;
 
#ifdef CONFIG_UDEBUG
/** Debugging stuff */
udebug_task_t udebug;
 
106,6 → 107,7
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/tracing/kernel/generic/include/proc/thread.h
205,8 → 205,11
/** Thread's kernel stack. */
uint8_t *kstack;
 
#ifdef CONFIG_UDEBUG
/** Debugging stuff */
udebug_thread_t udebug;
#endif
 
} thread_t;
 
/** Thread list lock.
/branches/tracing/kernel/generic/include/mm/as.h
225,8 → 225,12
extern int as_area_get_flags(as_area_t *area);
extern bool as_area_check_access(as_area_t *area, pf_access_t access);
extern size_t as_area_get_size(uintptr_t base);
 
#ifdef CONFIG_UDEBUG
extern int as_area_make_writeable(uintptr_t address);
extern int as_debug_write(uintptr_t va, void *data, size_t n);
#endif
 
extern int used_space_insert(as_area_t *a, uintptr_t page, count_t count);
extern int used_space_remove(as_area_t *a, uintptr_t page, count_t count);
 
/branches/tracing/kernel/generic/src/main/uinit.c
45,9 → 45,10
#include <proc/thread.h>
#include <userspace.h>
#include <mm/slab.h>
#include <arch.h>
#include <udebug/udebug.h>
#include <arch.h>
 
 
/** Thread used to bring up userspace thread.
*
* @param arg Pointer to structure containing userspace entry and stack
67,7 → 68,9
*/
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/tracing/kernel/generic/src/interrupt/interrupt.c
87,11 → 87,15
{
ASSERT(n < IVT_ITEMS);
 
#ifdef CONFIG_UDEBUG
if (THREAD) THREAD->udebug.uspace_state = istate;
#endif
exc_table[n].f(n + IVT_FIRST, istate);
 
#ifdef CONFIG_UDEBUG
if (THREAD) THREAD->udebug.uspace_state = NULL;
#endif
 
/* This is a safe place to exit exiting thread */
if (THREAD && THREAD->interrupted && istate_from_uspace(istate))
/branches/tracing/kernel/generic/src/time/clock.c
193,11 → 193,13
 
scheduler();
 
#ifdef CONFIG_UDEBUG
/*
* Give udebug chance to stop the thread
* before it begins executing.
*/
udebug_before_thread_runs();
#endif
}
}
 
/branches/tracing/kernel/generic/src/proc/task.c
156,6 → 156,7
ta->capabilities = 0;
ta->cycles = 0;
 
#ifdef CONFIG_UDEBUG
/* Init debugging stuff */
udebug_task_init(&ta->udebug);
 
164,6 → 165,7
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++)
/branches/tracing/kernel/generic/src/proc/thread.c
180,7 → 180,9
return -1;
}
 
#ifdef CONFIG_UDEBUG
mutex_initialize(&t->udebug.lock, MUTEX_PASSIVE);
#endif
 
return 0;
}
348,9 → 350,11
 
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,10 → 422,13
*/
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);
 
list_append(&t->th_link, &task->th_head);
spinlock_unlock(&task->lock);
 
445,9 → 452,10
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
752,8 → 760,10
thread_attach(t, TASK);
thread_ready(t);
 
#ifdef CONFIG_UDEBUG
/* Generate udebug THREAD_B event */
udebug_thread_b_event(t);
#endif
 
return 0;
} else
/branches/tracing/kernel/generic/src/mm/as.c
1107,6 → 1107,8
AS = new_as;
}
 
#ifdef CONFIG_UDEBUG
 
/** Write directly into a page, bypassing area flags.
*
* This allows a debugger to write into a page that is mapped read-only
1307,6 → 1309,8
return EOK;
}
 
#endif /* defined(CONFIG_UDEBUG) */
 
/** Convert address space area flags to page flags.
*
* @param aflags Flags of some address space area.
/branches/tracing/kernel/generic/src/syscall/syscall.c
101,13 → 101,18
unative_t a4, unative_t a5, unative_t a6, unative_t id)
{
unative_t rc;
 
#ifdef CONFIG_UDEBUG
istate_t fake_state;
 
THREAD->udebug.uspace_state = &fake_state;
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false);
#endif
 
if (id < SYSCALL_END) {
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
#endif
rc = syscall_table[id](a1, a2, a3, a4, a5, a6);
} else {
printf("Task %" PRIu64": Unknown syscall %#" PRIxn, TASK->taskid, id);
118,9 → 123,11
if (THREAD->interrupted)
thread_exit();
 
#ifdef CONFIG_UDEBUG
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true);
udebug_stoppable_end();
THREAD->udebug.uspace_state = NULL;
#endif
return rc;
}
/branches/tracing/kernel/generic/src/ipc/sysipc.c
342,8 → 342,10
return rc;
}
break;
#ifdef CONFIG_UDEBUG
case IPC_M_DEBUG_ALL:
return udebug_request_preprocess(call, phone);
#endif
default:
break;
}
888,6 → 890,7
*/
unative_t sys_ipc_connect_kbox(sysarg64_t *uspace_taskid_arg)
{
#ifdef CONFIG_UDEBUG
sysarg64_t taskid_arg;
int rc;
898,6 → 901,9
printf("sys_ipc_connect_kbox(%lld, %d)\n", taskid_arg.value);
 
return ipc_connect_kbox(taskid_arg.value);
#else
return (unative_t) ENOTSUP;
#endif
}
 
/** @}
/branches/tracing/kernel/generic/src/ipc/ipc.c
456,7 → 456,7
ipl_t ipl;
call_t *call;
 
call = ipc_call_alloc(0);
call = notify_box ? ipc_call_alloc(0) : NULL;
 
/* Disconnect all phones connected to our answerbox */
restart_phones:
510,6 → 510,8
if (call) ipc_call_free(call);
}
 
#ifdef CONFIG_UDEBUG
 
static void ipc_kbox_cleanup()
{
bool have_kb_thread;
546,6 → 548,7
spinlock_unlock(&TASK->kernel_box.lock);
}
 
#endif
 
/** Cleans up all IPC communication of the current task.
*
567,8 → 570,10
/* 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);
723,6 → 728,8
spinlock_unlock(&task->lock);
}
 
#ifdef CONFIG_UDEBUG
 
#include <ipc/ipcrsc.h>
#include <print.h>
#include <udebug/udebug_ipc.h>
864,5 → 871,7
return newphid;
}
 
#endif /* defined(CONFIG_UDEBUG) */
 
/** @}
*/
/branches/tracing/kernel/Makefile
150,6 → 150,10
endif
endif
 
ifeq ($(CONFIG_UDEBUG),y)
DEFS += -DCONFIG_UDEBUG
endif
 
## Simple detection for the type of the host system
#
HOST = $(shell uname)
280,12 → 284,19
generic/src/ipc/sysipc.c \
generic/src/ipc/ipcrsc.c \
generic/src/ipc/irq.c \
generic/src/udebug/udebug.c \
generic/src/udebug/udebug_ops.c \
generic/src/udebug/udebug_ipc.c \
generic/src/security/cap.c \
generic/src/sysinfo/sysinfo.c
 
## Udebug interface sources
#
 
ifeq ($(CONFIG_UDEBUG),y)
GENERIC_SOURCES += \
generic/src/udebug/udebug.c \
generic/src/udebug/udebug_ops.c \
generic/src/udebug/udebug_ipc.c
endif
 
## Test sources
#
 
/branches/tracing/kernel/arch/arm32/src/mm/page_fault.c
193,6 → 193,8
}
}
 
#ifdef CONFIG_UDEBUG
 
/** Check whether the abort was caused by a bkpt instruction.
*
* This must be called after (possibly) fetching the faulting page.
208,8 → 210,10
 
if ((opcode & 0xfff000f0) == 0xe1200070) {
/* Bkpt */
 
if (istate_from_uspace(istate)) {
udebug_breakpoint_event(0);
return;
} else {
panic("Unexpected BKPT instruction at 0x%x",
istate->pc);
217,6 → 221,8
}
}
 
#endif
 
/** Handles "prefetch abort" exception (instruction couldn't be executed).
*
* @param exc_no Exception number.
233,8 → 239,13
istate->pc);
}
 
#ifdef CONFIG_UDEBUG
/* Now check if the abort was caused by a breakpoint instruction */
bkpt_check(istate);
#else
panic("Unexpected BKPT instruction at 0x%x", istate->pc);
#endif
 
}
 
/** @}
/branches/tracing/kernel/arch/ppc32/src/interrupt.c
96,6 → 96,8
start_decrementer();
}
 
#ifdef CONFIG_UDEBUG
 
static void exception_program_trap(istate_t *istate)
{
if (istate_from_uspace(istate))
114,6 → 116,8
}
}
 
#endif
 
/* Initialize basic tables for exception dispatching */
void interrupt_init(void)
{
121,7 → 125,9
exc_register(VECTOR_INSTRUCTION_STORAGE, "instruction_storage", pht_refill);
exc_register(VECTOR_EXTERNAL, "external", exception_external);
exc_register(VECTOR_DECREMENTER, "timer", exception_decrementer);
#ifdef CONFIG_UDEBUG
exc_register(VECTOR_PROGRAM, "program", exception_program);
#endif
}
 
/** @}
/branches/tracing/kernel/arch/amd64/src/debugger.c
342,6 → 342,7
dr6 = read_dr6();
 
#ifdef CONFIG_UDEBUG
if (dr6 & DR6_BS) {
if (THREAD && istate_from_uspace(istate)) {
/*
352,6 → 353,7
return;
}
}
#endif
 
/* Set RF to restart the instruction */
#ifdef amd64
/branches/tracing/kernel/arch/mips32/src/exception.c
48,6 → 48,7
#include <console/kconsole.h>
#include <ddi/irq.h>
#include <arch/debugger.h>
#include <udebug/udebug.h>
 
static char * exctable[] = {
"Interrupt",
107,11 → 108,13
 
static void breakpoint_exception(int n, istate_t *istate)
{
#ifdef CONFIG_UDEBUG
if (istate_from_uspace(istate)) {
/* userspace breakpoint */
udebug_breakpoint_event(0);
return;
}
#endif
 
#ifdef CONFIG_DEBUG
debugger_bpoint(istate);
/branches/tracing/kernel/arch/ia32/Makefile.inc
160,5 → 160,10
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/boot/memmap.c \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/debugger.c \
arch/$(ARCH)/src/debugger.c
 
ifeq ($(CONFIG_UDEBUG),y)
ARCH_SOURCES += \
arch/$(ARCH)/src/breakpoint.c
endif
/branches/tracing/kernel/arch/ia32/src/ia32.c
98,8 → 98,11
/* Enable debugger */
debugger_init();
 
#ifdef CONFIG_UDEBUG
/* Enable INT3 breakpoint handler */
breakpoint_init();
#endif
/* Merge all memory zones to 1 big zone */
zone_merge_all();
}