当前位置: 首页 > 嵌入式底层BIOS > 正文

Intel处理器CPUID指令学习

前文《Intel处理器Family、Model、Stepping等的学习》只是简单讲了CPU的标识等内容(仅针对Intel,本文也是),但其读取方法未涉及。本文就此未完事宜来了解读取的方法:使用CPUID指令来完成。
Intel的IA32架构软件开发手册卷2(Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 2)中有专门章节讲CPUID。CPUID指令涉及到的内容较多,一一讲述不现实——文后附带地址有全面的介绍,可以前往学习。权威的说明请参考手册。本着实用的学习目的,本文根据常见的功能做说明,另外文中示例代码直接使用coreboot开源项目。
CPUID指令根据传递给EAX 寄存器的值,将对应的信息返回给 EAX、EBX、ECX 及 EDX 寄存器。从Intel手册上看,早期有的CPU是不支持CPUID指令的,但现在的处理器应该都支持了。通过EFLAGS寄存器可以知晓。该寄存器bit 21(ID)标志表示了处理器对CPUID指令的支持。
coreboot中,使用cpuid函数进行CPUID指令的操作,传入参数实际上即是手册中出现的eax的值。代码如下:

/*
* 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;
}

1、EAX=0,返回vendor id
执行CPUID后,返回值寄存器依次为EBX、EDX、ECX,其中EBX为“Genu”,EDX为“ineI”,ECX为“ntel”。手册解释如下:

EBX <- 756e6547h (* "Genu", with G in the low eight bits of BL *)
EDX <- 49656e69h (* "ineI", with i in the low eight bits of DL *)
ECX <- 6c65746eh (* "ntel", with n in the low eight bits of CL *)

这些寄存器组合起来,就是“GenuineIntel”。
实现示例:
coreboot项目src/arch/x86/cpu.c文件cpu_initialize函数。
下面根据wiki整理的已经知的CPU ID字符串:

"AMDisbetter!" – early engineering samples of AMD K5 processor
"AuthenticAMD" – AMD
"CentaurHauls" – Centaur (Including some VIA CPU)
"CyrixInstead" – Cyrix
"GenuineIntel" – Intel
"TransmetaCPU" – Transmeta
"GenuineTMx86" – Transmeta
"Geode by NSC" – National Semiconductor
"NexGenDriven" – NexGen
"RiseRiseRise" – Rise
"SiS SiS SiS " – SiS
"UMC UMC UMC " – UMC
"VIA VIA VIA " – VIA
"Vortex86 SoC" – Vortex

下面是虚拟机的CPU ID字符串:

"KVMKVMKVM" – KVM
"Microsoft Hv" – Microsoft Hyper-V or Windows Virtual PC
" lrpepyh vr" – Parallels (it possibly should be "prl hyperv ", but it is encoded as " lrpepyh vr")
"VMwareVMware" – VMware
"XenVMMXenVMM" – Xen HVM
 

2、EAX=0x01,返回Model、Family、Stepping信息
执行CPUID后,返回的EAX寄存器包含Model、Family、Stepping信息。各个字段解释如下图所示:

实现示例:
coreboot项目src/arch/x86/cpu.c文件cpu_initialize函数。
3、EAX=80000002h、80000003h、80000004h:返回处理器brand字符串
比如Atom的一款CPU的brand信息为:“Intel(R) Atom(TM) CPU E3815 @ 1.46GHz.”。
实现示例:
coreboot项目src/cpu/x86/mp_init.c文件init_bsp函数。

4、EAX=80000008h:返回虚拟地址和物理地址大小
物理地址的大小在EAX的bit[7:0]返回,虚拟地址的大小在EAX的bit[15:8]。
实现示例:
coreboot项目src/soc/intel/fsp_baytrail/ramstage.c文件fill_in_pattrs函数。

参考:
coreboot项目主页:http://www.coreboot.org/
Intel 64 and IA-32 Architectures Software Developer’s Manual手册下载地址:
http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
CPUID的wiki:https://en.wikipedia.org/wiki/CPUID
CPUID指令:http://hengch.blog.163.com/blog/static/1078006720091414224566/

李迟 2016.2.22 周一 元宵节夜

本文固定链接: http://www.latelee.org/firmware-bios/intel-cpuid-note.html

如无特别说明,迟思堂工作室文章均为原创,转载请注明: Intel处理器CPUID指令学习 | 迟思堂工作室

目前暂无评论

发表评论

*

快捷键:Ctrl+Enter