blob: 8d0af7bf090a4ce381a331bb188dab557b5aa0ca [file] [log] [blame]
Glauber de Oliveira Costac758ecf2008-01-30 13:31:03 +01001#ifndef __ASM_X86_PROCESSOR_H
2#define __ASM_X86_PROCESSOR_H
3
Glauber de Oliveira Costa053de042008-01-30 13:31:27 +01004#include <asm/processor-flags.h>
5
Glauber de Oliveira Costac72dcf82008-01-30 13:31:27 +01006#include <asm/page.h>
7#include <asm/system.h>
8
Glauber de Oliveira Costac758ecf2008-01-30 13:31:03 +01009static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
10 unsigned int *ecx, unsigned int *edx)
11{
12 /* ecx is often an input as well as an output. */
13 __asm__("cpuid"
14 : "=a" (*eax),
15 "=b" (*ebx),
16 "=c" (*ecx),
17 "=d" (*edx)
18 : "0" (*eax), "2" (*ecx));
19}
20
Glauber de Oliveira Costac72dcf82008-01-30 13:31:27 +010021static inline void load_cr3(pgd_t *pgdir)
22{
23 write_cr3(__pa(pgdir));
24}
Glauber de Oliveira Costac758ecf2008-01-30 13:31:03 +010025
Thomas Gleixner96a388d2007-10-11 11:20:03 +020026#ifdef CONFIG_X86_32
27# include "processor_32.h"
28#else
29# include "processor_64.h"
30#endif
Glauber de Oliveira Costac758ecf2008-01-30 13:31:03 +010031
Glauber de Oliveira Costa1b46cbe2008-01-30 13:31:27 +010032static inline unsigned long native_get_debugreg(int regno)
33{
34 unsigned long val = 0; /* Damn you, gcc! */
35
36 switch (regno) {
37 case 0:
38 asm("mov %%db0, %0" :"=r" (val)); break;
39 case 1:
40 asm("mov %%db1, %0" :"=r" (val)); break;
41 case 2:
42 asm("mov %%db2, %0" :"=r" (val)); break;
43 case 3:
44 asm("mov %%db3, %0" :"=r" (val)); break;
45 case 6:
46 asm("mov %%db6, %0" :"=r" (val)); break;
47 case 7:
48 asm("mov %%db7, %0" :"=r" (val)); break;
49 default:
50 BUG();
51 }
52 return val;
53}
54
55static inline void native_set_debugreg(int regno, unsigned long value)
56{
57 switch (regno) {
58 case 0:
59 asm("mov %0,%%db0" : /* no output */ :"r" (value));
60 break;
61 case 1:
62 asm("mov %0,%%db1" : /* no output */ :"r" (value));
63 break;
64 case 2:
65 asm("mov %0,%%db2" : /* no output */ :"r" (value));
66 break;
67 case 3:
68 asm("mov %0,%%db3" : /* no output */ :"r" (value));
69 break;
70 case 6:
71 asm("mov %0,%%db6" : /* no output */ :"r" (value));
72 break;
73 case 7:
74 asm("mov %0,%%db7" : /* no output */ :"r" (value));
75 break;
76 default:
77 BUG();
78 }
79}
80
81
Glauber de Oliveira Costac758ecf2008-01-30 13:31:03 +010082#ifndef CONFIG_PARAVIRT
83#define __cpuid native_cpuid
Glauber de Oliveira Costa1b46cbe2008-01-30 13:31:27 +010084#define paravirt_enabled() 0
85
86/*
87 * These special macros can be used to get or set a debugging register
88 */
89#define get_debugreg(var, register) \
90 (var) = native_get_debugreg(register)
91#define set_debugreg(value, register) \
92 native_set_debugreg(register, value)
93
94#endif /* CONFIG_PARAVIRT */
95
96/*
97 * Save the cr4 feature set we're using (ie
98 * Pentium 4MB enable and PPro Global page
99 * enable), so that any CPU's that boot up
100 * after us can get the correct flags.
101 */
102extern unsigned long mmu_cr4_features;
103
104static inline void set_in_cr4(unsigned long mask)
105{
106 unsigned cr4;
107 mmu_cr4_features |= mask;
108 cr4 = read_cr4();
109 cr4 |= mask;
110 write_cr4(cr4);
111}
112
113static inline void clear_in_cr4(unsigned long mask)
114{
115 unsigned cr4;
116 mmu_cr4_features &= ~mask;
117 cr4 = read_cr4();
118 cr4 &= ~mask;
119 write_cr4(cr4);
120}
121
122
Glauber de Oliveira Costac758ecf2008-01-30 13:31:03 +0100123
124/*
125 * Generic CPUID function
126 * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
127 * resulting in stale register contents being returned.
128 */
129static inline void cpuid(unsigned int op,
130 unsigned int *eax, unsigned int *ebx,
131 unsigned int *ecx, unsigned int *edx)
132{
133 *eax = op;
134 *ecx = 0;
135 __cpuid(eax, ebx, ecx, edx);
136}
137
138/* Some CPUID calls want 'count' to be placed in ecx */
139static inline void cpuid_count(unsigned int op, int count,
140 unsigned int *eax, unsigned int *ebx,
141 unsigned int *ecx, unsigned int *edx)
142{
143 *eax = op;
144 *ecx = count;
145 __cpuid(eax, ebx, ecx, edx);
146}
147
148/*
149 * CPUID functions returning a single datum
150 */
151static inline unsigned int cpuid_eax(unsigned int op)
152{
153 unsigned int eax, ebx, ecx, edx;
154
155 cpuid(op, &eax, &ebx, &ecx, &edx);
156 return eax;
157}
158static inline unsigned int cpuid_ebx(unsigned int op)
159{
160 unsigned int eax, ebx, ecx, edx;
161
162 cpuid(op, &eax, &ebx, &ecx, &edx);
163 return ebx;
164}
165static inline unsigned int cpuid_ecx(unsigned int op)
166{
167 unsigned int eax, ebx, ecx, edx;
168
169 cpuid(op, &eax, &ebx, &ecx, &edx);
170 return ecx;
171}
172static inline unsigned int cpuid_edx(unsigned int op)
173{
174 unsigned int eax, ebx, ecx, edx;
175
176 cpuid(op, &eax, &ebx, &ecx, &edx);
177 return edx;
178}
179
180#endif