diff options
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/include/arch/cpu.h | 6 | ||||
-rw-r--r-- | src/arch/x86/lib/Makefile.inc | 2 | ||||
-rw-r--r-- | src/arch/x86/lib/cpu.c | 26 | ||||
-rw-r--r-- | src/arch/x86/lib/cpu_common.c | 56 |
4 files changed, 63 insertions, 27 deletions
diff --git a/src/arch/x86/include/arch/cpu.h b/src/arch/x86/include/arch/cpu.h index ebb7cdfdfb..851b58dd49 100644 --- a/src/arch/x86/include/arch/cpu.h +++ b/src/arch/x86/include/arch/cpu.h @@ -142,8 +142,12 @@ static inline unsigned int cpuid_edx(unsigned int op) #define X86_VENDOR_ANY 0xfe #define X86_VENDOR_UNKNOWN 0xff -int cpu_phys_address_size(void); +#define CPUID_FEATURE_PAE (1 << 6) +#define CPUID_FEATURE_PSE36 (1 << 17) + +int cpu_cpuid_extended_level(void); int cpu_have_cpuid(void); +int cpu_phys_address_size(void); #ifndef __SIMPLE_DEVICE__ diff --git a/src/arch/x86/lib/Makefile.inc b/src/arch/x86/lib/Makefile.inc index 1b111d8c17..ccfe30ae67 100644 --- a/src/arch/x86/lib/Makefile.inc +++ b/src/arch/x86/lib/Makefile.inc @@ -2,6 +2,7 @@ ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32)$(CONFIG_ARCH_ROMSTAGE_X86_64),y) romstage-y += cbfs_and_run.c +romstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += cpu_common.c romstage-y += memset.c romstage-y += memcpy.c romstage-y += memmove.c @@ -13,6 +14,7 @@ ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32)$(CONFIG_ARCH_RAMSTAGE_X86_64),y) ramstage-y += c_start.S ramstage-y += cpu.c +ramstage-y += cpu_common.c ramstage-y += pci_ops_conf1.c ramstage-$(CONFIG_MMCONF_SUPPORT) += pci_ops_mmconf.c ramstage-y += exception.c diff --git a/src/arch/x86/lib/cpu.c b/src/arch/x86/lib/cpu.c index 86b5cb0cd4..db7269510b 100644 --- a/src/arch/x86/lib/cpu.c +++ b/src/arch/x86/lib/cpu.c @@ -31,12 +31,6 @@ static inline int flag_is_changeable_p(uint32_t flag) return ((f1^f2) & flag) != 0; } -/* Probe for the CPUID instruction */ -int cpu_have_cpuid(void) -{ - return flag_is_changeable_p(X86_EFLAGS_ID); -} - /* * Cyrix CPUs without cpuid or with cpuid not yet enabled can be detected * by the fact that they preserve the flags across the division of 5/2. @@ -130,26 +124,6 @@ static const char *cpu_vendor_name(int vendor) return name; } -static int cpu_cpuid_extended_level(void) -{ - return cpuid_eax(0x80000000); -} - -#define CPUID_FEATURE_PAE (1 << 6) -#define CPUID_FEATURE_PSE36 (1 << 17) - -int cpu_phys_address_size(void) -{ - if (!(cpu_have_cpuid())) - return 32; - - if (cpu_cpuid_extended_level() >= 0x80000008) - return cpuid_eax(0x80000008) & 0xff; - - if (cpuid_edx(1) & (CPUID_FEATURE_PAE | CPUID_FEATURE_PSE36)) - return 36; - return 32; -} static void identify_cpu(struct device *cpu) { char vendor_name[16]; diff --git a/src/arch/x86/lib/cpu_common.c b/src/arch/x86/lib/cpu_common.c new file mode 100644 index 0000000000..6c5561df98 --- /dev/null +++ b/src/arch/x86/lib/cpu_common.c @@ -0,0 +1,56 @@ +#include <console/console.h> +#include <cpu/cpu.h> +#include <arch/io.h> +#include <string.h> +#include <cpu/x86/mtrr.h> +#include <cpu/x86/msr.h> +#include <cpu/x86/lapic.h> +#include <arch/cpu.h> +#include <device/path.h> +#include <device/device.h> +#include <smp/spinlock.h> + +/* Standard macro to see if a specific flag is changeable */ +static inline int flag_is_changeable_p(uint32_t 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)); + return ((f1^f2) & flag) != 0; +} + +/* Probe for the CPUID instruction */ +int cpu_have_cpuid(void) +{ + return flag_is_changeable_p(X86_EFLAGS_ID); +} + +int cpu_cpuid_extended_level(void) +{ + return cpuid_eax(0x80000000); +} + +int cpu_phys_address_size(void) +{ + if (!(cpu_have_cpuid())) + return 32; + + if (cpu_cpuid_extended_level() >= 0x80000008) + return cpuid_eax(0x80000008) & 0xff; + + if (cpuid_edx(1) & (CPUID_FEATURE_PAE | CPUID_FEATURE_PSE36)) + return 36; + return 32; +} |