blob: 2dfcd72e95f0cc6cca27a7cb397ac4d280530ceb [file] [log] [blame]
Eric Biedermancadfd4c2004-10-14 20:52:22 +00001#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
25struct cpuid_result {
26 uint32_t eax;
27 uint32_t ebx;
28 uint32_t ecx;
29 uint32_t edx;
30};
Stefan Reinauer5f5436f2010-04-25 20:42:02 +000031
Eric Biedermancadfd4c2004-10-14 20:52:22 +000032/*
33 * Generic CPUID function
34 */
35static 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
Eric Biedermancadfd4c2004-10-14 20:52:22 +000048/*
49 * CPUID functions returning a single datum
50 */
51static 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}
Stefan Reinauer5f5436f2010-04-25 20:42:02 +000061
Eric Biedermancadfd4c2004-10-14 20:52:22 +000062static 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}
Stefan Reinauer5f5436f2010-04-25 20:42:02 +000072
Eric Biedermancadfd4c2004-10-14 20:52:22 +000073static 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}
Stefan Reinauer5f5436f2010-04-25 20:42:02 +000083
Eric Biedermancadfd4c2004-10-14 20:52:22 +000084static 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
Eric Biedermancadfd4c2004-10-14 20:52:22 +000095#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
Stefan Reinauer14e22772010-04-27 06:56:47 +0000105#define X86_VENDOR_SIS 10
Eric Biedermancadfd4c2004-10-14 20:52:22 +0000106#define X86_VENDOR_UNKNOWN 0xff
107
Stefan Reinauer35b6bbb2010-03-28 21:26:54 +0000108#if !defined(__PRE_RAM__)
Eric Biedermancadfd4c2004-10-14 20:52:22 +0000109#include <device/device.h>
110
Sven Schnelleadfbcb792012-01-10 12:01:43 +0100111int cpu_phys_address_size(void);
Rudolf Marek06253cd2012-02-25 23:51:12 +0100112int cpu_have_cpuid(void);
Sven Schnelleadfbcb792012-01-10 12:01:43 +0100113
Eric Biedermancadfd4c2004-10-14 20:52:22 +0000114struct cpu_device_id {
115 unsigned vendor;
116 unsigned device;
117};
Stefan Reinauer5f5436f2010-04-25 20:42:02 +0000118
Eric Biedermancadfd4c2004-10-14 20:52:22 +0000119struct cpu_driver {
120 struct device_operations *ops;
121 struct cpu_device_id *id_table;
122};
123
124struct cpu_info {
125 device_t cpu;
126 unsigned long index;
127};
128
129static inline struct cpu_info *cpu_info(void)
130{
131 struct cpu_info *ci;
132 __asm__("andl %%esp,%0; "
133 "orl %2, %0 "
Stefan Reinauer14e22772010-04-27 06:56:47 +0000134 :"=r" (ci)
135 : "0" (~(CONFIG_STACK_SIZE - 1)),
Stefan Reinauer08670622009-06-30 15:17:49 +0000136 "r" (CONFIG_STACK_SIZE - sizeof(struct cpu_info))
Eric Biedermancadfd4c2004-10-14 20:52:22 +0000137 );
138 return ci;
139}
140
141static inline unsigned long cpu_index(void)
142{
143 struct cpu_info *ci;
144 ci = cpu_info();
145 return ci->index;
146}
147
Yinghai Lud4b278c2006-10-04 20:46:15 +0000148struct 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
155static 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}
Eric Biedermancadfd4c2004-10-14 20:52:22 +0000166#endif
167
168#endif /* ARCH_CPU_H */