* 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
This commit is contained in:
Ingo Weinhold 2005-03-01 23:56:52 +00:00
parent c8d7534e5d
commit 98b14f8a6a
2 changed files with 30 additions and 2 deletions

View File

@ -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();

View File

@ -9,6 +9,7 @@
#include <thread.h>
#include <arch/thread.h>
#include <arch/user_debugger.h>
#include <arch_cpu.h>
#include <kernel.h>
#include <debug.h>
@ -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);
}