【问题标题】:Intel Processor : "If CPUID.06H:EAX.[7] = 1" Meaning?英特尔处理器:“如果 CPUID.06H:EAX.[7] = 1”是什么意思?
【发布时间】:2019-06-07 05:51:46
【问题描述】:

英特尔处理器数据表中的以下注释是什么意思?如何在 Linux 中的驱动程序代码中检查这一点?

如果 CPUID.06H:EAX.[7] = 1

我在寄存器描述表的 cmets 列中的英特尔处理器的 SW 开发人员手册中遇到了这种类型的语句..

参考:https://software.intel.com/sites/default/files/managed/22/0d/335592-sdm-vol-4.pdf

请帮助我理解处理器说明。

谢谢。

【问题讨论】:

  • 在 Linux 内核中有一个 API 可以检查 CPUID 并与您的期望匹配。 x86_match_cpu() 例如可以做一份工作。 OTOH 还有其他帮助程序可用于检查正在运行的 CPU 上的标志。

标签: linux-kernel linux-device-driver intel microprocessors


【解决方案1】:

CPUID.06H:EAX.[7] 可以发现 Intel 处理器中的 HWP(硬件控制的性能状态)支持。

如果未设置该功能位,则该功能不存在。访问 HWP MSR 将导致 #GP 异常。对于其他功能位,结果可能更糟:没有错误,但会导致以后难以调试的问题。


这意味着在指令前运行the cpuid instructioneax=0x6 之后,您应该检查eax 寄存器(特别是eax & (1<<7))。

要发现 Linux 内核中的 CPUID 值,您可以使用one of the cpuid functions, with op=6

#include  <asm/processor.h>   // defines the following:

void cpuid(unsigned int op,
             unsigned int *eax, unsigned int *ebx,
             unsigned int *ecx, unsigned int *edx);
void cpuid_count(unsigned int op, int count,
                   unsigned int *eax, unsigned int *ebx,
                   unsigned int *ecx, unsigned int *edx);

或者对于只需要一个注册结果的情况:

unsigned int cpuid_eax(unsigned int op);

并屏蔽 EAX 返回值。

一个小提示:引用 SDM 时最好指定一个部分 - 毕竟这是一本大书...

【讨论】:

  • 在未设置该位时访问 HWP GPR导致#GP 并在 Linux 上挂起该进程和内核,直到下次重新启动。 在调查 TurboBoost 转换惩罚下的性能计数器差异时,在那里,完成了,得到了伤痕
【解决方案2】:

问题 1

英特尔处理器数据表中的以下注释是什么意思?

If CPUID.06H:EAX.[7] = 1

cpuid 是一个特殊的处理器指令,用于发现处理器的详细信息(例如检查一些不常见功能的可用性)。它隐式使用 EAX 寄存器作为参数,并以 EAX、EBX、ECX、EDX 形式返回结果。 在 Intel 手册中,一般格式为:

CPUID.EAX_VALUE:RETURN_REGISTER.[BIT_NUMBER] = 1 : 表示如果你执行CPUID 指令,EAX 寄存器 = EAX_VALUE,你会在 RETURN_REGISTER 中得到结果。如果设置了位号BIT_NUMBER,那么它有一些特殊的含义,您可以在手册中找到。

CPUID.06H:EAX.[7]=1 表示如果您执行CPUID 指令,并将寄存器 EAX = 06H(十六进制为 6)作为输入,您将在 EAX 中得到结果。如果结果的第 7 位为 1,那么它有一些特殊的含义,您可以在手册中找到。例如。我在手册中读到了这一点:

HWP 基线资源和能力的可用性, CPUID.06H:EAX[bit 7]:如果该位被设置(即如果 CPUID.06H:EAX.[7]=1),HWP 提供了几个新的架构 MSR: IA32_PM_ENABLE,IA32_HWP_CAPABILITIES, IA32_HWP_REQUEST,IA32_HWP_STATUS。

问题 2

如何在 Linux 的驱动程序代码中检查这一点?

if(cpuid_eax(0x06) & (1<<7)){
   // Good news :features availlable, do your job
}else{
   // Bad luck ::
   return;
}

【讨论】:

  • 使用 & 代替 &&。 && 是逻辑与,仅检查两个操作数是否非零。 & 实际上将位掩码应用于返回值。
猜你喜欢
  • 1970-01-01
  • 2014-04-17
  • 1970-01-01
  • 1970-01-01
  • 2012-11-02
  • 1970-01-01
  • 2017-03-18
  • 2021-03-05
相关资源
最近更新 更多