Consolidate cpuid code.
This commit is contained in:
parent
c1bee64676
commit
c81acb7ff3
5 changed files with 22 additions and 124 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
2013-10-26 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Consolidate cpuid code.
|
||||||
|
|
||||||
2013-10-26 Vladimir Serbinenko <phcoder@gmail.com>
|
2013-10-26 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
Move cpuid code to cpuid.h and TSC code to tsc.c.
|
Move cpuid code to cpuid.h and TSC code to tsc.c.
|
||||||
|
|
|
@ -18,42 +18,10 @@
|
||||||
|
|
||||||
#include <grub/efiemu/efiemu.h>
|
#include <grub/efiemu/efiemu.h>
|
||||||
#include <grub/command.h>
|
#include <grub/command.h>
|
||||||
|
#include <grub/i386/cpuid.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)
|
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
grub_efiemu_get_default_core_name (void)
|
grub_efiemu_get_default_core_name (void)
|
||||||
{
|
{
|
||||||
|
return grub_cpuid_has_longmode ? "efiemu64.o" : "efiemu32.o";
|
||||||
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";
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,27 +41,11 @@ static __inline grub_uint64_t
|
||||||
grub_get_tsc (void)
|
grub_get_tsc (void)
|
||||||
{
|
{
|
||||||
grub_uint32_t lo, hi;
|
grub_uint32_t lo, hi;
|
||||||
|
grub_uint32_t a,b,c,d;
|
||||||
|
|
||||||
/* The CPUID instruction is a 'serializing' instruction, and
|
/* The CPUID instruction is a 'serializing' instruction, and
|
||||||
avoids out-of-order execution of the RDTSC instruction. */
|
avoids out-of-order execution of the RDTSC instruction. */
|
||||||
#ifdef __APPLE__
|
grub_cpuid (0,a,b,c,d);
|
||||||
__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
|
|
||||||
/* Read TSC value. We cannot use "=A", since this would use
|
/* Read TSC value. We cannot use "=A", since this would use
|
||||||
%rax on x86_64. */
|
%rax on x86_64. */
|
||||||
__asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi));
|
__asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi));
|
||||||
|
@ -72,34 +56,13 @@ grub_get_tsc (void)
|
||||||
static __inline int
|
static __inline int
|
||||||
grub_cpu_is_tsc_supported (void)
|
grub_cpu_is_tsc_supported (void)
|
||||||
{
|
{
|
||||||
|
grub_uint32_t a,b,c,d;
|
||||||
if (! grub_cpu_is_cpuid_supported ())
|
if (! grub_cpu_is_cpuid_supported ())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
grub_uint32_t features;
|
grub_cpuid(1,a,b,c,d);
|
||||||
#ifdef __APPLE__
|
|
||||||
__asm__ ("movl $1, %%eax\n\t"
|
return (d & (1 << 4)) != 0;
|
||||||
#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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -126,66 +126,22 @@ guessfsb (void)
|
||||||
{
|
{
|
||||||
const grub_uint64_t sane_value = 100000000;
|
const grub_uint64_t sane_value = 100000000;
|
||||||
grub_uint32_t manufacturer[3], max_cpuid, capabilities, msrlow;
|
grub_uint32_t manufacturer[3], max_cpuid, capabilities, msrlow;
|
||||||
|
grub_uint32_t a, b, d;
|
||||||
|
|
||||||
if (! grub_cpu_is_cpuid_supported ())
|
if (! grub_cpu_is_cpuid_supported ())
|
||||||
return sane_value;
|
return sane_value;
|
||||||
|
|
||||||
#ifdef __APPLE__
|
grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]);
|
||||||
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]));
|
|
||||||
|
|
||||||
/* Only Intel for now is done. */
|
/* Only Intel for now is done. */
|
||||||
if (grub_memcmp (manufacturer, "GenuineIntel", 12) != 0)
|
if (grub_memcmp (manufacturer, "GenuineIntel", 12) != 0)
|
||||||
return sane_value;
|
return sane_value;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check Speedstep. */
|
/* Check Speedstep. */
|
||||||
if (max_cpuid < 1)
|
if (max_cpuid < 1)
|
||||||
return sane_value;
|
return sane_value;
|
||||||
|
|
||||||
#ifdef __APPLE__
|
grub_cpuid (1, a, b, capabilities, d);
|
||||||
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
|
|
||||||
|
|
||||||
if (! (capabilities & (1 << 7)))
|
if (! (capabilities & (1 << 7)))
|
||||||
return sane_value;
|
return sane_value;
|
||||||
|
|
|
@ -69,9 +69,16 @@ grub_cpu_is_cpuid_supported (void)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __PIC__
|
||||||
#define grub_cpuid(num,a,b,c,d) \
|
#define grub_cpuid(num,a,b,c,d) \
|
||||||
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
|
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
|
||||||
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
|
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
|
||||||
: "0" (num))
|
: "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
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue