Browse Source

Shrink cpu.c and render it useful for our purposes.

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
adf192f566
2 changed files with 104 additions and 276 deletions
  1. 58
    73
      src/arch/i386/core/cpu.c
  2. 46
    203
      src/arch/i386/include/bits/cpu.h

+ 58
- 73
src/arch/i386/core/cpu.c View File

@@ -1,88 +1,73 @@
1
-#ifdef CONFIG_X86_64
2
-#include "stdint.h"
3
-#include "string.h"
4
-#include "bits/cpu.h"
5
-#include <gpxe/init.h>
1
+#include <stdint.h>
2
+#include <string.h>
3
+#include <cpu.h>
6 4
 
5
+/** @file
6
+ *
7
+ * CPU identification
8
+ *
9
+ */
7 10
 
8
-/* Standard macro to see if a specific flag is changeable */
9
-static inline int flag_is_changeable_p(uint32_t flag)
10
-{
11
+/**
12
+ * Test to see if CPU flag is changeable
13
+ *
14
+ * @v flag		Flag to test
15
+ * @ret can_change	Flag is changeable
16
+ */
17
+static inline int flag_is_changeable ( unsigned int flag ) {
11 18
 	uint32_t f1, f2;
12 19
 
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));
20
+	__asm__ ( "pushfl\n\t"
21
+		  "pushfl\n\t"
22
+		  "popl %0\n\t"
23
+		  "movl %0,%1\n\t"
24
+		  "xorl %2,%0\n\t"
25
+		  "pushl %0\n\t"
26
+		  "popfl\n\t"
27
+		  "pushfl\n\t"
28
+		  "popl %0\n\t"
29
+		  "popfl\n\t"
30
+		  : "=&r" ( f1 ), "=&r" ( f2 )
31
+		  : "ir" ( flag ) );
25 32
 
26
-	return ((f1^f2) & flag) != 0;
33
+	return ( ( ( f1 ^ f2 ) & flag ) != 0 );
27 34
 }
28 35
 
36
+/**
37
+ * Get CPU information
38
+ *
39
+ * @v cpu		CPU information structure to fill in
40
+ */
41
+void get_cpuinfo ( struct cpuinfo_x86 *cpu ) {
42
+	unsigned int cpuid_level;
43
+	unsigned int cpuid_extlevel;
44
+	unsigned int discard_1, discard_2, discard_3;
29 45
 
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 */
46
+	memset ( cpu, 0, sizeof ( *cpu ) );
47 47
 
48
-		/* If there are any capabilities, they'r vendor-specific */
49
-		/* enable_cpuid() would have set c->x86 for us. */
48
+	/* Check for CPUID instruction */
49
+	if ( ! flag_is_changeable ( X86_EFLAGS_ID ) ) {
50
+		DBG ( "CPUID not supported\n" );
51
+		return;
50 52
 	}
51
-	else {
52
-		/* CPU does have CPUID */
53 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
-		}
54
+	/* Get features, if present */
55
+	cpuid ( 0x00000000, &cpuid_level, &discard_1,
56
+		&discard_2, &discard_3 );
57
+	if ( cpuid_level >= 0x00000001 ) {
58
+		cpuid ( 0x00000001, &discard_1, &discard_2,
59
+			&discard_3, &cpu->features );
60
+	} else {
61
+		DBG ( "CPUID cannot return capabilities\n" );
62
+	}
72 63
 
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);
64
+	/* Get 64-bit features, if present */
65
+	cpuid ( 0x80000000, &cpuid_extlevel, &discard_1,
66
+		&discard_2, &discard_3 );
67
+	if ( ( cpuid_extlevel & 0xffff0000 ) == 0x80000000 ) {
68
+		if ( cpuid_extlevel >= 0x80000001 ) {
69
+			cpuid ( 0x80000001, &discard_1, &discard_2,
70
+				&discard_3, &cpu->amd_features );
78 71
 		}
79 72
 	}
80 73
 }
81
-
82
-struct cpuinfo_x86 cpu_info;
83
-void cpu_setup(void)
84
-{
85
-	identify_cpu(&cpu_info);
86
-}
87
-
88
-#endif /* CONFIG_X86_64 */

+ 46
- 203
src/arch/i386/include/bits/cpu.h View File

@@ -1,88 +1,54 @@
1 1
 #ifndef I386_BITS_CPU_H
2 2
 #define I386_BITS_CPU_H
3 3
 
4
-
5
-/* Sample usage: CPU_FEATURE_P(cpu.x86_capability, FPU) */
6
-#define CPU_FEATURE_P(CAP, FEATURE) \
7
-	(!!(CAP[(X86_FEATURE_##FEATURE)/32] & ((X86_FEATURE_##FEATURE) & 0x1f)))
8
-
9
-#define NCAPINTS	4	/* Currently we have 4 32-bit words worth of info */
10
-
11 4
 /* Intel-defined CPU features, CPUID level 0x00000001, word 0 */
12
-#define X86_FEATURE_FPU		(0*32+ 0) /* Onboard FPU */
13
-#define X86_FEATURE_VME		(0*32+ 1) /* Virtual Mode Extensions */
14
-#define X86_FEATURE_DE		(0*32+ 2) /* Debugging Extensions */
15
-#define X86_FEATURE_PSE 	(0*32+ 3) /* Page Size Extensions */
16
-#define X86_FEATURE_TSC		(0*32+ 4) /* Time Stamp Counter */
17
-#define X86_FEATURE_MSR		(0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
18
-#define X86_FEATURE_PAE		(0*32+ 6) /* Physical Address Extensions */
19
-#define X86_FEATURE_MCE		(0*32+ 7) /* Machine Check Architecture */
20
-#define X86_FEATURE_CX8		(0*32+ 8) /* CMPXCHG8 instruction */
21
-#define X86_FEATURE_APIC	(0*32+ 9) /* Onboard APIC */
22
-#define X86_FEATURE_SEP		(0*32+11) /* SYSENTER/SYSEXIT */
23
-#define X86_FEATURE_MTRR	(0*32+12) /* Memory Type Range Registers */
24
-#define X86_FEATURE_PGE		(0*32+13) /* Page Global Enable */
25
-#define X86_FEATURE_MCA		(0*32+14) /* Machine Check Architecture */
26
-#define X86_FEATURE_CMOV	(0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
27
-#define X86_FEATURE_PAT		(0*32+16) /* Page Attribute Table */
28
-#define X86_FEATURE_PSE36	(0*32+17) /* 36-bit PSEs */
29
-#define X86_FEATURE_PN		(0*32+18) /* Processor serial number */
30
-#define X86_FEATURE_CLFLSH	(0*32+19) /* Supports the CLFLUSH instruction */
31
-#define X86_FEATURE_DTES	(0*32+21) /* Debug Trace Store */
32
-#define X86_FEATURE_ACPI	(0*32+22) /* ACPI via MSR */
33
-#define X86_FEATURE_MMX		(0*32+23) /* Multimedia Extensions */
34
-#define X86_FEATURE_FXSR	(0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */
5
+#define X86_FEATURE_FPU		0 /* Onboard FPU */
6
+#define X86_FEATURE_VME		1 /* Virtual Mode Extensions */
7
+#define X86_FEATURE_DE		2 /* Debugging Extensions */
8
+#define X86_FEATURE_PSE 	3 /* Page Size Extensions */
9
+#define X86_FEATURE_TSC		4 /* Time Stamp Counter */
10
+#define X86_FEATURE_MSR		5 /* Model-Specific Registers, RDMSR, WRMSR */
11
+#define X86_FEATURE_PAE		6 /* Physical Address Extensions */
12
+#define X86_FEATURE_MCE		7 /* Machine Check Architecture */
13
+#define X86_FEATURE_CX8		8 /* CMPXCHG8 instruction */
14
+#define X86_FEATURE_APIC	9 /* Onboard APIC */
15
+#define X86_FEATURE_SEP		11 /* SYSENTER/SYSEXIT */
16
+#define X86_FEATURE_MTRR	12 /* Memory Type Range Registers */
17
+#define X86_FEATURE_PGE		13 /* Page Global Enable */
18
+#define X86_FEATURE_MCA		14 /* Machine Check Architecture */
19
+#define X86_FEATURE_CMOV	15 /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
20
+#define X86_FEATURE_PAT		16 /* Page Attribute Table */
21
+#define X86_FEATURE_PSE36	17 /* 36-bit PSEs */
22
+#define X86_FEATURE_PN		18 /* Processor serial number */
23
+#define X86_FEATURE_CLFLSH	19 /* Supports the CLFLUSH instruction */
24
+#define X86_FEATURE_DTES	21 /* Debug Trace Store */
25
+#define X86_FEATURE_ACPI	22 /* ACPI via MSR */
26
+#define X86_FEATURE_MMX		23 /* Multimedia Extensions */
27
+#define X86_FEATURE_FXSR	24 /* FXSAVE and FXRSTOR instructions (fast save and restore */
35 28
 				          /* of FPU context), and CR4.OSFXSR available */
36
-#define X86_FEATURE_XMM		(0*32+25) /* Streaming SIMD Extensions */
37
-#define X86_FEATURE_XMM2	(0*32+26) /* Streaming SIMD Extensions-2 */
38
-#define X86_FEATURE_SELFSNOOP	(0*32+27) /* CPU self snoop */
39
-#define X86_FEATURE_HT		(0*32+28) /* Hyper-Threading */
40
-#define X86_FEATURE_ACC		(0*32+29) /* Automatic clock control */
41
-#define X86_FEATURE_IA64	(0*32+30) /* IA-64 processor */
29
+#define X86_FEATURE_XMM		25 /* Streaming SIMD Extensions */
30
+#define X86_FEATURE_XMM2	26 /* Streaming SIMD Extensions-2 */
31
+#define X86_FEATURE_SELFSNOOP	27 /* CPU self snoop */
32
+#define X86_FEATURE_HT		28 /* Hyper-Threading */
33
+#define X86_FEATURE_ACC		29 /* Automatic clock control */
34
+#define X86_FEATURE_IA64	30 /* IA-64 processor */
42 35
 
43 36
 /* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
44 37
 /* Don't duplicate feature flags which are redundant with Intel! */
45
-#define X86_FEATURE_SYSCALL	(1*32+11) /* SYSCALL/SYSRET */
46
-#define X86_FEATURE_MMXEXT	(1*32+22) /* AMD MMX extensions */
47
-#define X86_FEATURE_LM		(1*32+29) /* Long Mode (x86-64) */
48
-#define X86_FEATURE_3DNOWEXT	(1*32+30) /* AMD 3DNow! extensions */
49
-#define X86_FEATURE_3DNOW	(1*32+31) /* 3DNow! */
50
-
51
-/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
52
-#define X86_FEATURE_RECOVERY	(2*32+ 0) /* CPU in recovery mode */
53
-#define X86_FEATURE_LONGRUN	(2*32+ 1) /* Longrun power control */
54
-#define X86_FEATURE_LRTI	(2*32+ 3) /* LongRun table interface */
55
-
56
-/* Other features, Linux-defined mapping, word 3 */
57
-/* This range is used for feature bits which conflict or are synthesized */
58
-#define X86_FEATURE_CXMMX	(3*32+ 0) /* Cyrix MMX extensions */
59
-#define X86_FEATURE_K6_MTRR	(3*32+ 1) /* AMD K6 nonstandard MTRRs */
60
-#define X86_FEATURE_CYRIX_ARR	(3*32+ 2) /* Cyrix ARRs (= MTRRs) */
61
-#define X86_FEATURE_CENTAUR_MCR	(3*32+ 3) /* Centaur MCRs (= MTRRs) */
38
+#define X86_FEATURE_SYSCALL	11 /* SYSCALL/SYSRET */
39
+#define X86_FEATURE_MMXEXT	22 /* AMD MMX extensions */
40
+#define X86_FEATURE_LM		29 /* Long Mode (x86-64) */
41
+#define X86_FEATURE_3DNOWEXT	30 /* AMD 3DNow! extensions */
42
+#define X86_FEATURE_3DNOW	31 /* 3DNow! */
62 43
 
63
-#define MAX_X86_VENDOR_ID 16
44
+/** x86 CPU information */
64 45
 struct cpuinfo_x86 {
65
-	uint8_t	 x86;		/* CPU family */
66
-	uint8_t	 x86_model;
67
-	uint8_t	 x86_mask;
68
-
69
-       	int	 cpuid_level;	/* Maximum supported CPUID level, -1=no CPUID */
70
-	unsigned x86_capability[NCAPINTS];
71
-	char	 x86_vendor_id[MAX_X86_VENDOR_ID];
46
+	/** CPU features */
47
+	unsigned int features;
48
+	/** 64-bit CPU features */
49
+	unsigned int amd_features;
72 50
 };
73 51
 
74
-
75
-#define X86_VENDOR_INTEL 0
76
-#define X86_VENDOR_CYRIX 1
77
-#define X86_VENDOR_AMD 2
78
-#define X86_VENDOR_UMC 3
79
-#define X86_VENDOR_NEXGEN 4
80
-#define X86_VENDOR_CENTAUR 5
81
-#define X86_VENDOR_RISE 6
82
-#define X86_VENDOR_TRANSMETA 7
83
-#define X86_VENDOR_NSC 8
84
-#define X86_VENDOR_UNKNOWN 0xff
85
-
86 52
 /*
87 53
  * EFLAGS bits
88 54
  */
@@ -107,137 +73,14 @@ struct cpuinfo_x86 {
107 73
 /*
108 74
  * Generic CPUID function
109 75
  */
110
-static inline void cpuid(int op, 
111
-	unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
112
-{
113
-	__asm__("cpuid"
114
-		: "=a" (*eax),
115
-		  "=b" (*ebx),
116
-		  "=c" (*ecx),
117
-		  "=d" (*edx)
118
-		: "0" (op));
119
-}
120
-
121
-/*
122
- * CPUID functions returning a single datum
123
- */
124
-static inline unsigned int cpuid_eax(unsigned int op)
125
-{
126
-	unsigned int eax;
127
-
128
-	__asm__("cpuid"
129
-		: "=a" (eax)
130
-		: "0" (op)
131
-		: "bx", "cx", "dx");
132
-	return eax;
133
-}
134
-static inline unsigned int cpuid_ebx(unsigned int op)
135
-{
136
-	unsigned int eax, ebx;
137
-
138
-	__asm__("cpuid"
139
-		: "=a" (eax), "=b" (ebx)
140
-		: "0" (op)
141
-		: "cx", "dx" );
142
-	return ebx;
143
-}
144
-static inline unsigned int cpuid_ecx(unsigned int op)
145
-{
146
-	unsigned int eax, ecx;
147
-
148
-	__asm__("cpuid"
149
-		: "=a" (eax), "=c" (ecx)
150
-		: "0" (op)
151
-		: "bx", "dx" );
152
-	return ecx;
76
+static inline __attribute__ (( always_inline )) void
77
+cpuid ( int op, unsigned int *eax, unsigned int *ebx,
78
+	unsigned int *ecx, unsigned int *edx ) {
79
+	__asm__ ( "cpuid" :
80
+		  "=a" ( *eax ), "=b" ( *ebx ), "=c" ( *ecx ), "=d" ( *edx )
81
+		: "0" ( op ) );
153 82
 }
154
-static inline unsigned int cpuid_edx(unsigned int op)
155
-{
156
-	unsigned int eax, edx;
157
-
158
-	__asm__("cpuid"
159
-		: "=a" (eax), "=d" (edx)
160
-		: "0" (op)
161
-		: "bx", "cx");
162
-	return edx;
163
-}
164
-
165
-/*
166
- * Intel CPU features in CR4
167
- */
168
-#define X86_CR4_VME		0x0001	/* enable vm86 extensions */
169
-#define X86_CR4_PVI		0x0002	/* virtual interrupts flag enable */
170
-#define X86_CR4_TSD		0x0004	/* disable time stamp at ipl 3 */
171
-#define X86_CR4_DE		0x0008	/* enable debugging extensions */
172
-#define X86_CR4_PSE		0x0010	/* enable page size extensions */
173
-#define X86_CR4_PAE		0x0020	/* enable physical address extensions */
174
-#define X86_CR4_MCE		0x0040	/* Machine check enable */
175
-#define X86_CR4_PGE		0x0080	/* enable global pages */
176
-#define X86_CR4_PCE		0x0100	/* enable performance counters at ipl 3 */
177
-#define X86_CR4_OSFXSR		0x0200	/* enable fast FPU save and restore */
178
-#define X86_CR4_OSXMMEXCPT	0x0400	/* enable unmasked SSE exceptions */
179
-
180
-
181
-#define MSR_K6_EFER			0xC0000080
182
-/* EFER bits: */ 
183
-#define _EFER_SCE 0  /* SYSCALL/SYSRET */
184
-#define _EFER_LME 8  /* Long mode enable */
185
-#define _EFER_LMA 10 /* Long mode active (read-only) */
186
-#define _EFER_NX 11  /* No execute enable */
187
-
188
-#define EFER_SCE (1<<_EFER_SCE)
189
-#define EFER_LME (1<<EFER_LME)
190
-#define EFER_LMA (1<<EFER_LMA)
191
-#define EFER_NX (1<<_EFER_NX)
192
-
193
-#define rdmsr(msr,val1,val2) \
194
-     __asm__ __volatile__("rdmsr" \
195
-			  : "=a" (val1), "=d" (val2) \
196
-			  : "c" (msr))
197
-
198
-#define wrmsr(msr,val1,val2) \
199
-     __asm__ __volatile__("wrmsr" \
200
-			  : /* no outputs */ \
201
-			  : "c" (msr), "a" (val1), "d" (val2))
202
-
203
-
204
-#define read_cr0()	({ \
205
-	unsigned int __dummy; \
206
-	__asm__( \
207
-		"movl %%cr0, %0\n\t" \
208
-		:"=r" (__dummy)); \
209
-	__dummy; \
210
-})
211
-#define write_cr0(x) \
212
-	__asm__("movl %0,%%cr0": :"r" (x));
213
-
214
-#define read_cr3()	({ \
215
-	unsigned int __dummy; \
216
-	__asm__( \
217
-		"movl %%cr3, %0\n\t" \
218
-		:"=r" (__dummy)); \
219
-	__dummy; \
220
-})
221
-#define write_cr3x(x) \
222
-	__asm__("movl %0,%%cr3": :"r" (x));
223
-
224
-
225
-#define read_cr4()	({ \
226
-	unsigned int __dummy; \
227
-	__asm__( \
228
-		"movl %%cr4, %0\n\t" \
229
-		:"=r" (__dummy)); \
230
-	__dummy; \
231
-})
232
-#define write_cr4x(x) \
233
-	__asm__("movl %0,%%cr4": :"r" (x));
234
-
235 83
 
236
-extern struct cpuinfo_x86 cpu_info;
237
-#ifdef CONFIG_X86_64
238
-extern void cpu_setup(void);
239
-#else
240
-#define cpu_setup() do {} while(0)
241
-#endif
84
+extern void get_cpuinfo ( struct cpuinfo_x86 *cpu );
242 85
 
243 86
 #endif /* I386_BITS_CPU_H */

Loading…
Cancel
Save