diff options
author | Bin Meng <bmeng.cn@gmail.com> | 2014-11-09 22:18:56 +0800 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2014-11-21 07:24:10 +0100 |
commit | 52f952bf5ecebc1de01269557591bad4ac62a01a (patch) | |
tree | 7a4c120112d12c48ef2e8f881dd4f67f79e04d86 /arch/x86/include/asm/cpu.h | |
parent | f67cd51e654ba6498230314b6e82b4dbbd4bfca7 (diff) |
x86: Do CPU identification in the early phase
The CPU identification happens in x86_cpu_init_f() and corresponding
fields are saved in the global data for later use.
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'arch/x86/include/asm/cpu.h')
-rw-r--r-- | arch/x86/include/asm/cpu.h | 168 |
1 files changed, 164 insertions, 4 deletions
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index 6c6774af76..89b748b392 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -1,16 +1,160 @@ /* * Copyright (c) 2014 The Chromium OS Authors. * + * Part of this file is adapted from coreboot + * src/arch/x86/include/arch/cpu.h and + * src/arch/x86/lib/cpu.c + * * SPDX-License-Identifier: GPL-2.0+ */ -#ifndef __X86_CPU_H -#define __X86_CPU_H +#ifndef _ASM_CPU_H +#define _ASM_CPU_H + +enum { + X86_VENDOR_INVALID = 0, + X86_VENDOR_INTEL, + X86_VENDOR_CYRIX, + X86_VENDOR_AMD, + X86_VENDOR_UMC, + X86_VENDOR_NEXGEN, + X86_VENDOR_CENTAUR, + X86_VENDOR_RISE, + X86_VENDOR_TRANSMETA, + X86_VENDOR_NSC, + X86_VENDOR_SIS, + X86_VENDOR_ANY = 0xfe, + X86_VENDOR_UNKNOWN = 0xff +}; + +struct cpuid_result { + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; +}; + +/* + * Generic CPUID function + */ +static inline struct cpuid_result cpuid(int op) +{ + struct cpuid_result result; + asm volatile( + "mov %%ebx, %%edi;" + "cpuid;" + "mov %%ebx, %%esi;" + "mov %%edi, %%ebx;" + : "=a" (result.eax), + "=S" (result.ebx), + "=c" (result.ecx), + "=d" (result.edx) + : "0" (op) + : "edi"); + return result; +} + +/* + * Generic Extended CPUID function + */ +static inline struct cpuid_result cpuid_ext(int op, unsigned ecx) +{ + struct cpuid_result result; + asm volatile( + "mov %%ebx, %%edi;" + "cpuid;" + "mov %%ebx, %%esi;" + "mov %%edi, %%ebx;" + : "=a" (result.eax), + "=S" (result.ebx), + "=c" (result.ecx), + "=d" (result.edx) + : "0" (op), "2" (ecx) + : "edi"); + return result; +} + +/* + * CPUID functions returning a single datum + */ +static inline unsigned int cpuid_eax(unsigned int op) +{ + unsigned int eax; + + __asm__("mov %%ebx, %%edi;" + "cpuid;" + "mov %%edi, %%ebx;" + : "=a" (eax) + : "0" (op) + : "ecx", "edx", "edi"); + return eax; +} + +static inline unsigned int cpuid_ebx(unsigned int op) +{ + unsigned int eax, ebx; + + __asm__("mov %%ebx, %%edi;" + "cpuid;" + "mov %%ebx, %%esi;" + "mov %%edi, %%ebx;" + : "=a" (eax), "=S" (ebx) + : "0" (op) + : "ecx", "edx", "edi"); + return ebx; +} + +static inline unsigned int cpuid_ecx(unsigned int op) +{ + unsigned int eax, ecx; - /** + __asm__("mov %%ebx, %%edi;" + "cpuid;" + "mov %%edi, %%ebx;" + : "=a" (eax), "=c" (ecx) + : "0" (op) + : "edx", "edi"); + return ecx; +} + +static inline unsigned int cpuid_edx(unsigned int op) +{ + unsigned int eax, edx; + + __asm__("mov %%ebx, %%edi;" + "cpuid;" + "mov %%edi, %%ebx;" + : "=a" (eax), "=d" (edx) + : "0" (op) + : "ecx", "edi"); + return edx; +} + +/* 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; +} + +/** * cpu_enable_paging_pae() - Enable PAE-paging * - * @pdpt: Value to set in cr3 (PDPT or PML4T) + * @cr3: Value to set in cr3 (PDPT or PML4T) */ void cpu_enable_paging_pae(ulong cr3); @@ -27,6 +171,22 @@ void cpu_disable_paging_pae(void); int cpu_has_64bit(void); /** + * cpu_vendor_name() - Get CPU vendor name + * + * @vendor: CPU vendor enumeration number + * + * @return: Address to hold the CPU vendor name string + */ +const char *cpu_vendor_name(int vendor); + +/** + * fill_processor_name() - Get processor name + * + * @processor_name: Address to hold the processor name string + */ +void fill_processor_name(char *processor_name); + +/** * cpu_call64() - Jump to a 64-bit Linux kernel (internal function) * * The kernel is uncompressed and the 64-bit entry point is expected to be |