From 98b14f8a6a92e75a9a6958543e93d7b4fcdf64bb Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Tue, 1 Mar 2005 23:56:52 +0000 Subject: [PATCH] * Made i386_get_current_iframe() static again, since it wasn't what was needed to get the topmost user iframe. Added i386_get_user_iframe() for exactly that purpose. * Added reinitialization of user debugging for the new thread when switching the context. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11523 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/arch/x86/arch_thread.h | 2 +- src/kernel/core/arch/x86/arch_thread.c | 30 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/headers/private/kernel/arch/x86/arch_thread.h b/headers/private/kernel/arch/x86/arch_thread.h index 9f85bfe634..2465c19688 100644 --- a/headers/private/kernel/arch/x86/arch_thread.h +++ b/headers/private/kernel/arch/x86/arch_thread.h @@ -17,7 +17,7 @@ extern "C" { void i386_push_iframe(struct thread *t, struct iframe *frame); void i386_pop_iframe(struct thread *t); -struct iframe *i386_get_current_iframe(void); +struct iframe *i386_get_user_iframe(void); void i386_return_from_signal(); void i386_end_return_from_signal(); diff --git a/src/kernel/core/arch/x86/arch_thread.c b/src/kernel/core/arch/x86/arch_thread.c index 3a24cf9e03..92a36797d3 100755 --- a/src/kernel/core/arch/x86/arch_thread.c +++ b/src/kernel/core/arch/x86/arch_thread.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -78,7 +79,7 @@ i386_pop_iframe(struct thread *thread) * from standard kernel threads. */ -struct iframe * +static struct iframe * i386_get_current_iframe(void) { struct thread *thread = thread_get_current_thread(); @@ -88,6 +89,28 @@ i386_get_current_iframe(void) } +/** \brief Returns the current thread's topmost (i.e. most recent) + * userland->kernel transition iframe (usually the first one, save for + * interrupts in signal handlers). + * \return The iframe, or \c NULL, if there is no such iframe (e.g. when + * the thread is a kernel thread). + */ +struct iframe * +i386_get_user_iframe(void) +{ + struct thread *thread = thread_get_current_thread(); + int i; + + for (i = thread->arch_info.iframe_ptr - 1; i >= 0; i--) { + struct iframe *frame = thread->arch_info.iframes[i]; + if (frame->cs == USER_CODE_SEG) + return frame; + } + + return NULL; +} + + static inline void set_fs_register(uint32 segment) { @@ -247,6 +270,11 @@ arch_thread_context_switch(struct thread *t_from, struct thread *t_to) if (((uint32)new_pgdir % B_PAGE_SIZE) != 0) panic("arch_thread_context_switch: bad pgdir 0x%lx\n", new_pgdir); + // reinit debugging; necessary, if the thread was preempted after + // initializing debugging before returning to userland + if (t_to->team->aspace != NULL) + i386_reinit_user_debug_after_context_switch(t_to); + i386_fsave_swap(t_from->arch_info.fpu_state, t_to->arch_info.fpu_state); i386_context_switch(&t_from->arch_info, &t_to->arch_info, (addr_t)new_pgdir); }