diff options
| author | Michael Brown | 2007-07-14 20:12:13 +0200 |
|---|---|---|
| committer | Michael Brown | 2007-07-14 20:12:13 +0200 |
| commit | adf192f56633f90d500015c3f0e0ae74cc92ac10 (patch) | |
| tree | 5ad3390483921aec470f399620be246076144c9a /src/arch/i386/core | |
| parent | Reduced etherboot.h dependencies to avoid unnecessary rebuilds. (diff) | |
| download | ipxe-adf192f56633f90d500015c3f0e0ae74cc92ac10.tar.gz ipxe-adf192f56633f90d500015c3f0e0ae74cc92ac10.tar.xz ipxe-adf192f56633f90d500015c3f0e0ae74cc92ac10.zip | |
Shrink cpu.c and render it useful for our purposes.
Diffstat (limited to 'src/arch/i386/core')
| -rw-r--r-- | src/arch/i386/core/cpu.c | 131 |
1 files changed, 58 insertions, 73 deletions
diff --git a/src/arch/i386/core/cpu.c b/src/arch/i386/core/cpu.c index cbef6a1af..c24fa4e69 100644 --- a/src/arch/i386/core/cpu.c +++ b/src/arch/i386/core/cpu.c @@ -1,88 +1,73 @@ -#ifdef CONFIG_X86_64 -#include "stdint.h" -#include "string.h" -#include "bits/cpu.h" -#include <gpxe/init.h> +#include <stdint.h> +#include <string.h> +#include <cpu.h> +/** @file + * + * CPU identification + * + */ -/* Standard macro to see if a specific flag is changeable */ -static inline int flag_is_changeable_p(uint32_t flag) -{ +/** + * Test to see if CPU flag is changeable + * + * @v flag Flag to test + * @ret can_change Flag is changeable + */ +static inline int flag_is_changeable ( unsigned int flag ) { uint32_t f1, f2; - asm("pushfl\n\t" - "pushfl\n\t" - "popl %0\n\t" - "movl %0,%1\n\t" - "xorl %2,%0\n\t" - "pushl %0\n\t" - "popfl\n\t" - "pushfl\n\t" - "popl %0\n\t" - "popfl\n\t" - : "=&r" (f1), "=&r" (f2) - : "ir" (flag)); + __asm__ ( "pushfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "movl %0,%1\n\t" + "xorl %2,%0\n\t" + "pushl %0\n\t" + "popfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "popfl\n\t" + : "=&r" ( f1 ), "=&r" ( f2 ) + : "ir" ( flag ) ); - return ((f1^f2) & flag) != 0; + return ( ( ( f1 ^ f2 ) & flag ) != 0 ); } +/** + * Get CPU information + * + * @v cpu CPU information structure to fill in + */ +void get_cpuinfo ( struct cpuinfo_x86 *cpu ) { + unsigned int cpuid_level; + unsigned int cpuid_extlevel; + unsigned int discard_1, discard_2, discard_3; -/* Probe for the CPUID instruction */ -static inline int have_cpuid_p(void) -{ - return flag_is_changeable_p(X86_EFLAGS_ID); -} - -static void identify_cpu(struct cpuinfo_x86 *c) -{ - unsigned xlvl; - - c->cpuid_level = -1; /* CPUID not detected */ - c->x86_model = c->x86_mask = 0; /* So far unknown... */ - c->x86_vendor_id[0] = '\0'; /* Unset */ - memset(&c->x86_capability, 0, sizeof c->x86_capability); - - if (!have_cpuid_p()) { - /* CPU doesn'thave CPUID */ + memset ( cpu, 0, sizeof ( *cpu ) ); - /* If there are any capabilities, they'r vendor-specific */ - /* enable_cpuid() would have set c->x86 for us. */ + /* Check for CPUID instruction */ + if ( ! flag_is_changeable ( X86_EFLAGS_ID ) ) { + DBG ( "CPUID not supported\n" ); + return; } - else { - /* CPU does have CPUID */ - /* Get vendor name */ - cpuid(0x00000000, &c->cpuid_level, - (int *)&c->x86_vendor_id[0], - (int *)&c->x86_vendor_id[8], - (int *)&c->x86_vendor_id[4]); - - /* Initialize the standard set of capabilities */ - /* Note that the vendor-specific code below might override */ - - /* Intel-defined flags: level 0x00000001 */ - if ( c->cpuid_level >= 0x00000001 ) { - unsigned tfms, junk; - cpuid(0x00000001, &tfms, &junk, &junk, - &c->x86_capability[0]); - c->x86 = (tfms >> 8) & 15; - c->x86_model = (tfms >> 4) & 15; - c->x86_mask = tfms & 15; - } + /* Get features, if present */ + cpuid ( 0x00000000, &cpuid_level, &discard_1, + &discard_2, &discard_3 ); + if ( cpuid_level >= 0x00000001 ) { + cpuid ( 0x00000001, &discard_1, &discard_2, + &discard_3, &cpu->features ); + } else { + DBG ( "CPUID cannot return capabilities\n" ); + } - /* AMD-defined flags: level 0x80000001 */ - xlvl = cpuid_eax(0x80000000); - if ( (xlvl & 0xffff0000) == 0x80000000 ) { - if ( xlvl >= 0x80000001 ) - c->x86_capability[1] = cpuid_edx(0x80000001); + /* Get 64-bit features, if present */ + cpuid ( 0x80000000, &cpuid_extlevel, &discard_1, + &discard_2, &discard_3 ); + if ( ( cpuid_extlevel & 0xffff0000 ) == 0x80000000 ) { + if ( cpuid_extlevel >= 0x80000001 ) { + cpuid ( 0x80000001, &discard_1, &discard_2, + &discard_3, &cpu->amd_features ); } } } - -struct cpuinfo_x86 cpu_info; -void cpu_setup(void) -{ - identify_cpu(&cpu_info); -} - -#endif /* CONFIG_X86_64 */ |
