We don't actually use the reset functions anywhere, and nothing really
[people/sha0/gpxe.git] / src / arch / i386 / core / cpu.c
1 #ifdef CONFIG_X86_64
2 #include "stdint.h"
3 #include "string.h"
4 #include "bits/cpu.h"
5 #include <gpxe/init.h>
6
7
8 /* Standard macro to see if a specific flag is changeable */
9 static inline int flag_is_changeable_p(uint32_t flag)
10 {
11         uint32_t f1, f2;
12
13         asm("pushfl\n\t"
14             "pushfl\n\t"
15             "popl %0\n\t"
16             "movl %0,%1\n\t"
17             "xorl %2,%0\n\t"
18             "pushl %0\n\t"
19             "popfl\n\t"
20             "pushfl\n\t"
21             "popl %0\n\t"
22             "popfl\n\t"
23             : "=&r" (f1), "=&r" (f2)
24             : "ir" (flag));
25
26         return ((f1^f2) & flag) != 0;
27 }
28
29
30 /* Probe for the CPUID instruction */
31 static inline int have_cpuid_p(void)
32 {
33         return flag_is_changeable_p(X86_EFLAGS_ID);
34 }
35
36 static void identify_cpu(struct cpuinfo_x86 *c)
37 {
38         unsigned xlvl;
39
40         c->cpuid_level = -1;            /* CPUID not detected */
41         c->x86_model = c->x86_mask = 0; /* So far unknown... */
42         c->x86_vendor_id[0] = '\0';     /* Unset */
43         memset(&c->x86_capability, 0, sizeof c->x86_capability);
44         
45         if (!have_cpuid_p()) {
46                 /* CPU doesn'thave CPUID */
47
48                 /* If there are any capabilities, they'r vendor-specific */
49                 /* enable_cpuid() would have set c->x86 for us. */
50         }
51         else {
52                 /* CPU does have CPUID */
53
54                 /* Get vendor name */
55                 cpuid(0x00000000, &c->cpuid_level,
56                       (int *)&c->x86_vendor_id[0],
57                       (int *)&c->x86_vendor_id[8],
58                       (int *)&c->x86_vendor_id[4]);
59                 
60                 /* Initialize the standard set of capabilities */
61                 /* Note that the vendor-specific code below might override */
62
63                 /* Intel-defined flags: level 0x00000001 */
64                 if ( c->cpuid_level >= 0x00000001 ) {
65                         unsigned tfms, junk;
66                         cpuid(0x00000001, &tfms, &junk, &junk,
67                               &c->x86_capability[0]);
68                         c->x86 = (tfms >> 8) & 15;
69                         c->x86_model = (tfms >> 4) & 15;
70                         c->x86_mask = tfms & 15;
71                 }
72
73                 /* AMD-defined flags: level 0x80000001 */
74                 xlvl = cpuid_eax(0x80000000);
75                 if ( (xlvl & 0xffff0000) == 0x80000000 ) {
76                         if ( xlvl >= 0x80000001 )
77                                 c->x86_capability[1] = cpuid_edx(0x80000001);
78                 }
79         }
80 }
81
82 struct cpuinfo_x86 cpu_info;
83 void cpu_setup(void)
84 {
85         identify_cpu(&cpu_info);
86 }
87
88 INIT_FN ( INIT_CPU, cpu_setup, NULL );
89
90 #endif /* CONFIG_X86_64 */