2dfcd72e95f0cc6cca27a7cb397ac4d280530ceb
[coreboot.git] / src / arch / x86 / include / arch / cpu.h
1 #ifndef ARCH_CPU_H
2 #define ARCH_CPU_H
3
4 /*
5  * EFLAGS bits
6  */
7 #define X86_EFLAGS_CF   0x00000001 /* Carry Flag */
8 #define X86_EFLAGS_PF   0x00000004 /* Parity Flag */
9 #define X86_EFLAGS_AF   0x00000010 /* Auxillary carry Flag */
10 #define X86_EFLAGS_ZF   0x00000040 /* Zero Flag */
11 #define X86_EFLAGS_SF   0x00000080 /* Sign Flag */
12 #define X86_EFLAGS_TF   0x00000100 /* Trap Flag */
13 #define X86_EFLAGS_IF   0x00000200 /* Interrupt Flag */
14 #define X86_EFLAGS_DF   0x00000400 /* Direction Flag */
15 #define X86_EFLAGS_OF   0x00000800 /* Overflow Flag */
16 #define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */
17 #define X86_EFLAGS_NT   0x00004000 /* Nested Task */
18 #define X86_EFLAGS_RF   0x00010000 /* Resume Flag */
19 #define X86_EFLAGS_VM   0x00020000 /* Virtual Mode */
20 #define X86_EFLAGS_AC   0x00040000 /* Alignment Check */
21 #define X86_EFLAGS_VIF  0x00080000 /* Virtual Interrupt Flag */
22 #define X86_EFLAGS_VIP  0x00100000 /* Virtual Interrupt Pending */
23 #define X86_EFLAGS_ID   0x00200000 /* CPUID detection flag */
24
25 struct cpuid_result {
26         uint32_t eax;
27         uint32_t ebx;
28         uint32_t ecx;
29         uint32_t edx;
30 };
31
32 /*
33  * Generic CPUID function
34  */
35 static inline struct cpuid_result cpuid(int op)
36 {
37         struct cpuid_result result;
38         asm volatile(
39                 "cpuid"
40                 : "=a" (result.eax),
41                   "=b" (result.ebx),
42                   "=c" (result.ecx),
43                   "=d" (result.edx)
44                 : "0" (op));
45         return result;
46 }
47
48 /*
49  * CPUID functions returning a single datum
50  */
51 static inline unsigned int cpuid_eax(unsigned int op)
52 {
53         unsigned int eax;
54
55         __asm__("cpuid"
56                 : "=a" (eax)
57                 : "0" (op)
58                 : "ebx", "ecx", "edx");
59         return eax;
60 }
61
62 static inline unsigned int cpuid_ebx(unsigned int op)
63 {
64         unsigned int eax, ebx;
65
66         __asm__("cpuid"
67                 : "=a" (eax), "=b" (ebx)
68                 : "0" (op)
69                 : "ecx", "edx" );
70         return ebx;
71 }
72
73 static inline unsigned int cpuid_ecx(unsigned int op)
74 {
75         unsigned int eax, ecx;
76
77         __asm__("cpuid"
78                 : "=a" (eax), "=c" (ecx)
79                 : "0" (op)
80                 : "ebx", "edx" );
81         return ecx;
82 }
83
84 static inline unsigned int cpuid_edx(unsigned int op)
85 {
86         unsigned int eax, edx;
87
88         __asm__("cpuid"
89                 : "=a" (eax), "=d" (edx)
90                 : "0" (op)
91                 : "ebx", "ecx");
92         return edx;
93 }
94
95 #define X86_VENDOR_INVALID    0
96 #define X86_VENDOR_INTEL      1
97 #define X86_VENDOR_CYRIX      2
98 #define X86_VENDOR_AMD        3
99 #define X86_VENDOR_UMC        4
100 #define X86_VENDOR_NEXGEN     5
101 #define X86_VENDOR_CENTAUR    6
102 #define X86_VENDOR_RISE       7
103 #define X86_VENDOR_TRANSMETA  8
104 #define X86_VENDOR_NSC        9
105 #define X86_VENDOR_SIS       10
106 #define X86_VENDOR_UNKNOWN 0xff
107
108 #if !defined(__PRE_RAM__)
109 #include <device/device.h>
110
111 int cpu_phys_address_size(void);
112 int cpu_have_cpuid(void);
113
114 struct cpu_device_id {
115         unsigned vendor;
116         unsigned device;
117 };
118
119 struct cpu_driver {
120         struct device_operations *ops;
121         struct cpu_device_id *id_table;
122 };
123
124 struct cpu_info {
125         device_t cpu;
126         unsigned long index;
127 };
128
129 static inline struct cpu_info *cpu_info(void)
130 {
131         struct cpu_info *ci;
132         __asm__("andl %%esp,%0; "
133                 "orl  %2, %0 "
134                 :"=r" (ci)
135                 : "0" (~(CONFIG_STACK_SIZE - 1)),
136                 "r" (CONFIG_STACK_SIZE - sizeof(struct cpu_info))
137         );
138         return ci;
139 }
140
141 static inline unsigned long cpu_index(void)
142 {
143         struct cpu_info *ci;
144         ci = cpu_info();
145         return ci->index;
146 }
147
148 struct cpuinfo_x86 {
149         uint8_t    x86;            /* CPU family */
150         uint8_t    x86_vendor;     /* CPU vendor */
151         uint8_t    x86_model;
152         uint8_t    x86_mask;
153 };
154
155 static void inline get_fms(struct cpuinfo_x86 *c, uint32_t tfms)
156 {
157         c->x86 = (tfms >> 8) & 0xf;
158         c->x86_model = (tfms >> 4) & 0xf;
159         c->x86_mask = tfms & 0xf;
160         if (c->x86 == 0xf)
161                 c->x86 += (tfms >> 20) & 0xff;
162         if (c->x86 >= 0x6)
163                 c->x86_model += ((tfms >> 16) & 0xF) << 4;
164
165 }
166 #endif
167
168 #endif /* ARCH_CPU_H */