+2013-10-26 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Consolidate cpuid code.
+
2013-10-26 Vladimir Serbinenko <phcoder@gmail.com>
Move cpuid code to cpuid.h and TSC code to tsc.c.
#include <grub/efiemu/efiemu.h>
#include <grub/command.h>
-
-#define cpuid(num,a,b,c,d) \
- asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
- : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
- : "0" (num))
-
-#define bit_LM (1 << 29)
+#include <grub/i386/cpuid.h>
const char *
grub_efiemu_get_default_core_name (void)
{
-
- unsigned int eax, ebx, ecx, edx;
- unsigned int max_level;
- unsigned int ext_level;
-
- /* See if we can use cpuid. */
- asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
- "pushl %0; popfl; pushfl; popl %0; popfl"
- : "=&r" (eax), "=&r" (ebx)
- : "i" (0x00200000));
- if (((eax ^ ebx) & 0x00200000) == 0)
- return "efiemu32.o";
-
- /* Check the highest input value for eax. */
- cpuid (0, eax, ebx, ecx, edx);
- /* We only look at the first four characters. */
- max_level = eax;
- if (max_level == 0)
- return "efiemu32.o";
-
- cpuid (0x80000000, eax, ebx, ecx, edx);
- ext_level = eax;
- if (ext_level < 0x80000000)
- return "efiemu32.o";
-
- cpuid (0x80000001, eax, ebx, ecx, edx);
- return (edx & bit_LM) ? "efiemu64.o" : "efiemu32.o";
+ return grub_cpuid_has_longmode ? "efiemu64.o" : "efiemu32.o";
}
grub_get_tsc (void)
{
grub_uint32_t lo, hi;
+ grub_uint32_t a,b,c,d;
/* The CPUID instruction is a 'serializing' instruction, and
avoids out-of-order execution of the RDTSC instruction. */
-#ifdef __APPLE__
- __asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
-#ifdef __x86_64__
- "push %%rbx\n"
-#else
- "push %%ebx\n"
-#endif
- "cpuid\n"
-#ifdef __x86_64__
- "pop %%rbx\n"
-#else
- "pop %%ebx\n"
-#endif
- :::"%rax", "%rcx", "%rdx");
-#else
- __asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
- "cpuid":::"%rax", "%rbx", "%rcx", "%rdx");
-#endif
+ grub_cpuid (0,a,b,c,d);
/* Read TSC value. We cannot use "=A", since this would use
%rax on x86_64. */
__asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi));
static __inline int
grub_cpu_is_tsc_supported (void)
{
+ grub_uint32_t a,b,c,d;
if (! grub_cpu_is_cpuid_supported ())
return 0;
- grub_uint32_t features;
-#ifdef __APPLE__
- __asm__ ("movl $1, %%eax\n\t"
-#ifdef __x86_64__
- "push %%rbx\n"
-#else
- "push %%ebx\n"
-#endif
- "cpuid\n"
-#ifdef __x86_64__
- "pop %%rbx\n"
-#else
- "pop %%ebx\n"
-#endif
- : "=d" (features)
- : /* No inputs. */
- : /* Clobbered: */ "%rax", "%rcx");
-#else
- __asm__ ("movl $1, %%eax\n\t"
- "cpuid\n"
- : "=d" (features)
- : /* No inputs. */
- : /* Clobbered: */ "%rax", "%rbx", "%rcx");
-#endif
- return (features & (1 << 4)) != 0;
+ grub_cpuid(1,a,b,c,d);
+
+ return (d & (1 << 4)) != 0;
}
static void
{
const grub_uint64_t sane_value = 100000000;
grub_uint32_t manufacturer[3], max_cpuid, capabilities, msrlow;
+ grub_uint32_t a, b, d;
if (! grub_cpu_is_cpuid_supported ())
return sane_value;
-#ifdef __APPLE__
- asm volatile ("movl $0, %%eax\n"
-#ifdef __x86_64__
- "push %%rbx\n"
-#else
- "push %%ebx\n"
-#endif
- "cpuid\n"
-#ifdef __x86_64__
- "pop %%rbx\n"
-#else
- "pop %%ebx\n"
-#endif
- : "=a" (max_cpuid),
- "=d" (manufacturer[1]), "=c" (manufacturer[2]));
-
- /* Only Intel for now is done. */
- if (grub_memcmp (manufacturer + 1, "ineIntel", 12) != 0)
- return sane_value;
-
-#else
- asm volatile ("movl $0, %%eax\n"
- "cpuid"
- : "=a" (max_cpuid), "=b" (manufacturer[0]),
- "=d" (manufacturer[1]), "=c" (manufacturer[2]));
+ grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]);
/* Only Intel for now is done. */
if (grub_memcmp (manufacturer, "GenuineIntel", 12) != 0)
return sane_value;
-#endif
/* Check Speedstep. */
if (max_cpuid < 1)
return sane_value;
-#ifdef __APPLE__
- asm volatile ("movl $1, %%eax\n"
-#ifdef __x86_64__
- "push %%rbx\n"
-#else
- "push %%ebx\n"
-#endif
- "cpuid\n"
-#ifdef __x86_64__
- "pop %%rbx\n"
-#else
- "pop %%ebx\n"
-#endif
- : "=c" (capabilities):
- : "%rax", "%rdx");
-#else
- asm volatile ("movl $1, %%eax\n"
- "cpuid"
- : "=c" (capabilities):
- : "%rax", "%rbx", "%rdx");
-#endif
+ grub_cpuid (1, a, b, capabilities, d);
if (! (capabilities & (1 << 7)))
return sane_value;
#endif
+#ifdef __PIC__
#define grub_cpuid(num,a,b,c,d) \
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
: "0" (num))
+#else
+#define grub_cpuid(num,a,b,c,d) \
+ asm volatile ("cpuid" \
+ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
+ : "0" (num))
+#endif
#endif