/* * Copyright 2002-2011, The Haiku Team. All rights reserved. * Distributed under the terms of the MIT License. * * Copyright 2002, Travis Geiselbrecht. All rights reserved. * Distributed under the terms of the NewOS License. */ #ifndef _KERNEL_ARCH_x86_THREAD_H #define _KERNEL_ARCH_x86_THREAD_H #include #ifdef __cplusplus extern "C" { #endif struct sigaction; struct iframe* x86_get_user_iframe(void); struct iframe* x86_get_current_iframe(void); struct iframe* x86_get_thread_user_iframe(Thread* thread); phys_addr_t x86_next_page_directory(Thread* from, Thread* to); void x86_initial_return_to_userland(Thread* thread, struct iframe* iframe); void x86_restart_syscall(struct iframe* frame); void x86_set_tls_context(Thread* thread); static inline Thread* arch_thread_get_current_thread(void) { addr_t addr; __asm__("mov %%gs:0, %0" : "=r"(addr)); return (Thread*)addr; } #ifdef __x86_64__ static inline void arch_thread_set_current_thread(Thread* t) { // Point GS segment base at thread architecture data. t->arch_info.thread = t; x86_write_msr(IA32_MSR_GS_BASE, (addr_t)&t->arch_info); } #ifdef _COMPAT_MODE static inline void arch_thread_set_ds(unsigned short ds) { asm volatile("mov %0, %%ds" : : "r" (ds) : "memory"); } static inline void arch_thread_set_es(unsigned short es) { asm volatile("mov %0, %%es" : : "r" (es) : "memory"); } // override empty macro #undef arch_syscall_64_bit_return_value void arch_syscall_64_bit_return_value(void); #endif // _COMPAT_MODE #else // __x86_64__ // override empty macro #undef arch_syscall_64_bit_return_value void arch_syscall_64_bit_return_value(void); static inline void arch_thread_set_current_thread(Thread* t) { asm volatile("mov %0, %%gs:0" : : "r" (t) : "memory"); } #endif // __x86_64__ #ifdef __cplusplus } #endif #endif /* _KERNEL_ARCH_x86_THREAD_H */