svn commit: r344118 - head/sys/i386/include
Konstantin Belousov
kib at FreeBSD.org
Thu Feb 14 13:53:12 UTC 2019
Author: kib
Date: Thu Feb 14 13:53:11 2019
New Revision: 344118
URL: https://svnweb.freebsd.org/changeset/base/344118
Log:
Provide userspace versions of do_cpuid() and cpuid_count() on i386.
Some older compilers, when generating PIC code, cannot handle inline
asm that clobbers %ebx (because %ebx is used as the GOT offset
register). Userspace versions avoid clobbering %ebx by saving it to
stack before executing the CPUID instruction.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Modified:
head/sys/i386/include/cpufunc.h
Modified: head/sys/i386/include/cpufunc.h
==============================================================================
--- head/sys/i386/include/cpufunc.h Thu Feb 14 09:50:59 2019 (r344117)
+++ head/sys/i386/include/cpufunc.h Thu Feb 14 13:53:11 2019 (r344118)
@@ -108,21 +108,47 @@ disable_intr(void)
__asm __volatile("cli" : : : "memory");
}
+#ifdef _KERNEL
static __inline void
do_cpuid(u_int ax, u_int *p)
{
__asm __volatile("cpuid"
- : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
- : "0" (ax));
+ : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
+ : "0" (ax));
}
static __inline void
cpuid_count(u_int ax, u_int cx, u_int *p)
{
__asm __volatile("cpuid"
- : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
- : "0" (ax), "c" (cx));
+ : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
+ : "0" (ax), "c" (cx));
}
+#else
+static __inline void
+do_cpuid(u_int ax, u_int *p)
+{
+ __asm __volatile(
+ "pushl\t%%ebx\n\t"
+ "cpuid\n\t"
+ "movl\t%%ebx,%1\n\t"
+ "popl\t%%ebx"
+ : "=a" (p[0]), "=DS" (p[1]), "=c" (p[2]), "=d" (p[3])
+ : "0" (ax));
+}
+
+static __inline void
+cpuid_count(u_int ax, u_int cx, u_int *p)
+{
+ __asm __volatile(
+ "pushl\t%%ebx\n\t"
+ "cpuid\n\t"
+ "movl\t%%ebx,%1\n\t"
+ "popl\t%%ebx"
+ : "=a" (p[0]), "=DS" (p[1]), "=c" (p[2]), "=d" (p[3])
+ : "0" (ax), "c" (cx));
+}
+#endif
static __inline void
enable_intr(void)
More information about the svn-src-all
mailing list