Main Page   File List  

cpu.h

Go to the documentation of this file.
00001 
00007 /* (c) 2004 Technische Universitaet Dresden
00008  * This file is part of DROPS, which is distributed under the terms of the
00009  * GNU General Public License 2. Please see the COPYING file for details. */
00010 
00011 #ifndef __L4_UTIL_CPU_H
00012 #define __L4_UTIL_CPU_H
00013 
00014 #include <l4/sys/compiler.h>
00015 
00016 EXTERN_C_BEGIN
00017 
00026 L4_INLINE int          l4util_cpu_has_cpuid(void);
00027 
00035 L4_INLINE unsigned int l4util_cpu_capabilities(void);
00036 
00043 L4_INLINE unsigned int l4util_cpu_capabilities_nocheck(void);
00044 
00049 L4_INLINE void
00050 l4util_cpu_cpuid(unsigned long mode,
00051                  unsigned long *eax, unsigned long *ebx,
00052                  unsigned long *ecx, unsigned long *edx);
00053 
00054 static inline void
00055 l4util_cpu_pause(void)
00056 {
00057   __asm__ __volatile__ ("rep; nop");
00058 }
00059 
00060 L4_INLINE int
00061 l4util_cpu_has_cpuid(void)
00062 {
00063   unsigned long eax;
00064 
00065   asm volatile("pushfl                  \t\n"
00066                "popl %%eax              \t\n" /* get eflags */
00067                "movl %%eax, %%ebx       \t\n" /* save it */
00068                "xorl $0x200000, %%eax   \t\n" /* toggle ID bit */
00069                "pushl %%eax             \t\n" 
00070                "popfl                   \t\n" /* set again */
00071                "pushfl                  \t\n"
00072                "popl %%eax              \t\n" /* get it again */
00073                "xorl %%eax, %%ebx       \t\n"
00074                "pushl %%ebx             \t\n"
00075                "popfl                   \t\n" /* restore saved flags */
00076                : "=a" (eax)
00077                : /* no input */
00078                : "ebx");
00079 
00080   return eax & 0x200000;
00081 }
00082 
00083 L4_INLINE void
00084 l4util_cpu_cpuid(unsigned long mode,
00085                  unsigned long *eax, unsigned long *ebx,
00086                  unsigned long *ecx, unsigned long *edx)
00087 {
00088   asm volatile("cpuid"
00089                : "=a" (*eax),
00090                  "=b" (*ebx),
00091                  "=c" (*ecx),
00092                  "=d" (*edx)
00093                : "a"  (mode)
00094                : "cc");
00095 }
00096 
00097 L4_INLINE unsigned int
00098 l4util_cpu_capabilities_nocheck(void)
00099 {
00100   unsigned long dummy, capability;
00101 
00102   /* get CPU capabilities */
00103   l4util_cpu_cpuid(1, &dummy, &dummy, &dummy, &capability);
00104 
00105   return capability;
00106 }
00107 
00108 L4_INLINE unsigned int
00109 l4util_cpu_capabilities(void)
00110 {
00111   if (!l4util_cpu_has_cpuid())
00112     return 0; /* CPU has not cpuid instruction */
00113 
00114   return l4util_cpu_capabilities_nocheck();
00115 }
00116 
00117 EXTERN_C_END
00118 
00119 #endif
00120 

L4 Utilities, part of DROPS  © 2000-2003