Intel处理器MSR学习

Intel IA32软件开发者手册第3卷第35章中介绍了MSR。但是,该章节并没有十分详细地描述,基本上就给出一个地址并作简单说明。而网络上能搜索到文章,也是点到即止。本文结合IA32开发手册,以及coreboot代码,概要地整理一下这方面的知识,用实例来展示MSR用途。

一、概念

MSR是“Model Specific Registers” (直译为”模型特定寄存器“)的缩写。正如其名它和处理器的Model密切相关,不同的Model,哪怕只相差一个迭代版本,MSR也会有不同。需要用CPUID指令读取DisplayFamily和DisplayModel,从而得知该处理器(包括不同的系列或模型(model))能使用的MSR范围。有些MSR一旦确定就不会再改变,这类MSR被称为”ARCHITECTURAL MSRS“,手册使用前缀”IA32_“表示,如寄存器地址为0x17的名称为IA32_PLATFORM_ID,表示处理器平台类型,下文将以此作为实例演示msr用法。

二、操作方法

MSR是一组64 位寄存器,分别通过rdmsr和wrmsr 指令进行读和写操作。使用rdmsr读取到的64比特数据分别放到edx和eax (分别为高低32比特)。而使用wrmsr写时,高低32比特数据分别放到edx和eax中,另外寄存器偏移存于ecx中。在coreboot代码中,使用rdmsr()和wrmsr函数分别进行msr的读、写操作。具体实现如下:

typedef struct msr_struct
{
unsigned lo;
unsigned hi;
} msr_t;

static inline __attribute__((always_inline)) msr_t rdmsr(unsigned index)
{
msr_t result;
__asm__ __volatile__ (
"rdmsr"
: "=a" (result.lo), "=d" (result.hi)
: "c" (index)
);
return result;
}

static inline __attribute__((always_inline)) void wrmsr(unsigned index, msr_t msr)
{
__asm__ __volatile__ (
"wrmsr"
: /* No outputs */
: "c" (index), "a" (msr.lo), "d" (msr.hi)
);
}

代码使用的内嵌汇编靖参考前面文章,本文不再赘述。

三、例子

读取Intel处理器Baytrail为例,读取其平台类型使用msr读取寄存器0x17(MSR_IA32_PLATFORM_ID)。coreboot项目代码如下:

// 打印CPU芯片类型
#define VARIANT_ID_BYTE 18
#define VARIANT_ID_MASK 7
void report_platform_info(void)
{
const char *baytrail_variants[4] = {
"Bay Trail-I (ISG/embedded)",
"Bay Trail-T (Tablet)",
"Bay Trail-D (Desktop)",
"Bay Trail-M (Mobile)",
};
msr_t platform_id = rdmsr(MSR_IA32_PLATFORM_ID);
uint8_t variant = (platform_id.hi >> VARIANT_ID_BYTE) & VARIANT_ID_MASK;


printk(BIOS_INFO, "Baytrail Chip Variant: %s\n", variant < 4 ?
      baytrail_variants[variant] : "Unknown");
print_dram_info();
}

注:截止本文发表时,未能找到“#define VARIANT_ID_BYTE 18”的依据。

另:邓志的《x86/x64体系探索及编程》中也有涉及MSR,建议去看看。

四、参考

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


李迟  2016.2.25 

你可能感兴趣的:(微机/硬件底层/BIOS)