Upgraded GRUB2 to 2.00 release.
[AROS.git] / arch / all-pc / boot / grub2-aros / include / grub / i386 / tsc.h
blob2442d7e24921fa906203d76480079fc14fc7ee6c
1 /*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2008,2009 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef KERNEL_CPU_TSC_HEADER
20 #define KERNEL_CPU_TSC_HEADER 1
22 #include <grub/types.h>
24 /* Read the TSC value, which increments with each CPU clock cycle. */
25 static __inline grub_uint64_t
26 grub_get_tsc (void)
28 grub_uint32_t lo, hi;
30 /* The CPUID instruction is a 'serializing' instruction, and
31 avoids out-of-order execution of the RDTSC instruction. */
32 #ifdef __APPLE__
33 __asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
34 #ifdef __x86_64__
35 "push %%rbx\n"
36 #else
37 "push %%ebx\n"
38 #endif
39 "cpuid\n"
40 #ifdef __x86_64__
41 "pop %%rbx\n"
42 #else
43 "pop %%ebx\n"
44 #endif
45 :::"%rax", "%rcx", "%rdx");
46 #else
47 __asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
48 "cpuid":::"%rax", "%rbx", "%rcx", "%rdx");
49 #endif
50 /* Read TSC value. We cannot use "=A", since this would use
51 %rax on x86_64. */
52 __asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi));
54 return (((grub_uint64_t) hi) << 32) | lo;
57 #ifdef __x86_64__
59 static __inline int
60 grub_cpu_is_cpuid_supported (void)
62 grub_uint64_t id_supported;
64 __asm__ ("pushfq\n\t"
65 "popq %%rax /* Get EFLAGS into EAX */\n\t"
66 "movq %%rax, %%rcx /* Save original flags in ECX */\n\t"
67 "xorq $0x200000, %%rax /* Flip ID bit in EFLAGS */\n\t"
68 "pushq %%rax /* Store modified EFLAGS on stack */\n\t"
69 "popfq /* Replace current EFLAGS */\n\t"
70 "pushfq /* Read back the EFLAGS */\n\t"
71 "popq %%rax /* Get EFLAGS into EAX */\n\t"
72 "xorq %%rcx, %%rax /* Check if flag could be modified */\n\t"
73 : "=a" (id_supported)
74 : /* No inputs. */
75 : /* Clobbered: */ "%rcx");
77 return id_supported != 0;
80 #else
82 static __inline int
83 grub_cpu_is_cpuid_supported (void)
85 grub_uint32_t id_supported;
87 __asm__ ("pushfl\n\t"
88 "popl %%eax /* Get EFLAGS into EAX */\n\t"
89 "movl %%eax, %%ecx /* Save original flags in ECX */\n\t"
90 "xorl $0x200000, %%eax /* Flip ID bit in EFLAGS */\n\t"
91 "pushl %%eax /* Store modified EFLAGS on stack */\n\t"
92 "popfl /* Replace current EFLAGS */\n\t"
93 "pushfl /* Read back the EFLAGS */\n\t"
94 "popl %%eax /* Get EFLAGS into EAX */\n\t"
95 "xorl %%ecx, %%eax /* Check if flag could be modified */\n\t"
96 : "=a" (id_supported)
97 : /* No inputs. */
98 : /* Clobbered: */ "%rcx");
100 return id_supported != 0;
103 #endif
105 static __inline int
106 grub_cpu_is_tsc_supported (void)
108 if (! grub_cpu_is_cpuid_supported ())
109 return 0;
111 grub_uint32_t features;
112 #ifdef __APPLE__
113 __asm__ ("movl $1, %%eax\n\t"
114 #ifdef __x86_64__
115 "push %%rbx\n"
116 #else
117 "push %%ebx\n"
118 #endif
119 "cpuid\n"
120 #ifdef __x86_64__
121 "pop %%rbx\n"
122 #else
123 "pop %%ebx\n"
124 #endif
125 : "=d" (features)
126 : /* No inputs. */
127 : /* Clobbered: */ "%rax", "%rcx");
128 #else
129 __asm__ ("movl $1, %%eax\n\t"
130 "cpuid\n"
131 : "=d" (features)
132 : /* No inputs. */
133 : /* Clobbered: */ "%rax", "%rbx", "%rcx");
134 #endif
135 return (features & (1 << 4)) != 0;
138 void grub_tsc_init (void);
139 grub_uint64_t grub_tsc_get_time_ms (void);
141 #endif /* ! KERNEL_CPU_TSC_HEADER */