15c48b108SAl Viro /* 25c48b108SAl Viro * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 35c48b108SAl Viro * Licensed under the GPL 45c48b108SAl Viro */ 55c48b108SAl Viro 65c48b108SAl Viro #ifndef __UM_PROCESSOR_I386_H 75c48b108SAl Viro #define __UM_PROCESSOR_I386_H 85c48b108SAl Viro 95c48b108SAl Viro #include <linux/string.h> 105c48b108SAl Viro #include <sysdep/host_ldt.h> 115c48b108SAl Viro #include <asm/segment.h> 125c48b108SAl Viro 135c48b108SAl Viro extern int host_has_cmov; 145c48b108SAl Viro 155c48b108SAl Viro struct uml_tls_struct { 165c48b108SAl Viro struct user_desc tls; 175c48b108SAl Viro unsigned flushed:1; 185c48b108SAl Viro unsigned present:1; 195c48b108SAl Viro }; 205c48b108SAl Viro 215c48b108SAl Viro struct arch_thread { 225c48b108SAl Viro struct uml_tls_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; 235c48b108SAl Viro unsigned long debugregs[8]; 245c48b108SAl Viro int debugregs_seq; 255c48b108SAl Viro struct faultinfo faultinfo; 265c48b108SAl Viro }; 275c48b108SAl Viro 285c48b108SAl Viro #define INIT_ARCH_THREAD { \ 295c48b108SAl Viro .tls_array = { [ 0 ... GDT_ENTRY_TLS_ENTRIES - 1 ] = \ 305c48b108SAl Viro { .present = 0, .flushed = 0 } }, \ 315c48b108SAl Viro .debugregs = { [ 0 ... 7 ] = 0 }, \ 325c48b108SAl Viro .debugregs_seq = 0, \ 335c48b108SAl Viro .faultinfo = { 0, 0, 0 } \ 345c48b108SAl Viro } 355c48b108SAl Viro 365c48b108SAl Viro static inline void arch_flush_thread(struct arch_thread *thread) 375c48b108SAl Viro { 385c48b108SAl Viro /* Clear any TLS still hanging */ 395c48b108SAl Viro memset(&thread->tls_array, 0, sizeof(thread->tls_array)); 405c48b108SAl Viro } 415c48b108SAl Viro 425c48b108SAl Viro static inline void arch_copy_thread(struct arch_thread *from, 435c48b108SAl Viro struct arch_thread *to) 445c48b108SAl Viro { 455c48b108SAl Viro memcpy(&to->tls_array, &from->tls_array, sizeof(from->tls_array)); 465c48b108SAl Viro } 475c48b108SAl Viro 485c48b108SAl Viro #include <asm/user.h> 495c48b108SAl Viro 505c48b108SAl Viro /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ 515c48b108SAl Viro static inline void rep_nop(void) 525c48b108SAl Viro { 535c48b108SAl Viro __asm__ __volatile__("rep;nop": : :"memory"); 545c48b108SAl Viro } 555c48b108SAl Viro 565c48b108SAl Viro #define cpu_relax() rep_nop() 575c48b108SAl Viro 585c48b108SAl Viro /* 595c48b108SAl Viro * Default implementation of macro that returns current 605c48b108SAl Viro * instruction pointer ("program counter"). Stolen 615c48b108SAl Viro * from asm-i386/processor.h 625c48b108SAl Viro */ 635c48b108SAl Viro #define current_text_addr() \ 645c48b108SAl Viro ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; }) 655c48b108SAl Viro 665c48b108SAl Viro #define ARCH_IS_STACKGROW(address) \ 675c48b108SAl Viro (address + 32 >= UPT_SP(¤t->thread.regs.regs)) 685c48b108SAl Viro 695c48b108SAl Viro #define KSTK_EIP(tsk) KSTK_REG(tsk, EIP) 705c48b108SAl Viro #define KSTK_ESP(tsk) KSTK_REG(tsk, UESP) 715c48b108SAl Viro #define KSTK_EBP(tsk) KSTK_REG(tsk, EBP) 725c48b108SAl Viro 735c48b108SAl Viro #endif 74