我正在尝试使用CPUID,但附加了一些字符串。根据{{3}},CPUID标准函数0000_0004h及以上仅在MISC_ENABLE.LCMV标志设置为0时才起作用。该标志是模型专用寄存器(MSR)1A0的第22位。显然,这种限制是由于Windows NT中的一个错误(感谢我让我更容易,微软;)。)
我可以使用CPUID 0000_0001h(ecx标志,第3位)测试是否存在LCMV标志。假设它存在,究竟是什么,为什么它对CPUID有这样的影响? MSR 1A0是读/写寄存器还是只读?如何使用汇编代码读取/写入这样的专用寄存器?
如果寄存器在技术上是读/写,那么在将CPU 22指令恢复到原始设置之前,将第22位复位为0是否安全?或者如果设置不正确(即启用),我几乎搞砸了?
最后,sandpile.org's CPUID page使用了“只有在MISC_ENABLE.LCMV设置为0时才启用此级别。这是由于Windows NT错误。”如果由于这个原因特别禁用了一堆标准级别,那么这是否会反映在CPUID级别0000_000h的eax寄存器(最大支持的标准级别)的输出中?
Phew ......我认为就是这样。
答案 0 :(得分:5)
您需要下载Intel® 64 and IA-32 Architectures Software Developer’s Manuals,因为它包含所有请求的信息。
我可以使用CPUID 0000_0001h(ecx标志,第3位)测试是否存在LCMV标志。假设它存在,究竟是什么,为什么它对CPUID有这样的影响?
标志的全名(参见Vol. 3B B-17)是“限制CPUID MaxVal”并将其效果表示为“当此位设置为1时,CPUID.00H在EAX中返回最大值[7:0] ] 3“。
MSR 1A0是读/写寄存器还是只读?
根据英特尔手册进行读/写(有一点需要注意,请继续阅读)。
如何使用汇编代码读取/写入这样的专用寄存器?
您使用RDMSR
(Vol.2B 4-301)阅读并使用WRMSR
(第2B卷4-505)进行了阅读,但请注意,它们要求您以实模式或特权运行0级(又称内核模式)。
如果寄存器在技术上是读/写,那么在将CPU 22指令恢复到原始设置之前,将第22位复位为0是否安全?或者如果设置不正确(即启用),我几乎搞砸了?
它应该只设置在有缺陷的操作系统上,你不应该清除它。如果您正在编写自己的内核,请继续并清除它,因为您自己声明它仅适用于NT和类似情况的错误版本。
最后,sandpile使用的措辞是“只有在MISC_ENABLE.LCMV设置为0时才启用此级别。这是由于Windows NT错误。”如果由于这个原因特别禁用了一堆标准级别,那么这是否会反映在CPUID级别0000_000h的eax寄存器(最大支持的标准级别)的输出中?
是的,它专门用于强制它在这种情况下返回3(参见上面的描述)。
答案 1 :(得分:3)
我只是稍微补充一下上面给出的非常全面的答案。 (我会将其添加为评论,但我还无法添加评论。)英特尔工程师在https://software.intel.com/en-us/forums/topic/306523?language=en#comment-1590394提供了有关该问题的更多历史详细信息,并从那里引用了少量格式化/拼写修复:
某些BIOS版本具有菜单设置,允许用户限制CPUID在下次重新启动后将支持的最大值(或叶索引)。 BIOS提供此选项仅仅是为了允许最终用户解决Microsoft Windows * NT 4.0安装问题,因为Windows NT 4.0的安装程序有一个错误,如果CPUID报告它支持更高版本,则会蓝屏3.启用BIOS选项以限制CPUID EAX maxvalue为3仅用于安装Windows NT 4.0。在所有其他情况下,BIOS应配置为不限制CPUID EAX最大值。
当CPUID受限于它不支持高于3的叶片时,在Intel Pentium 4及更高版本的处理器上,叶子3 [也]不受支持,因此请求CPUID报告叶子4将从CPUID上接收数据叶2(最高叶指数)。当软件使用无效的EAX输入值(即叶索引)执行CPUID时,CPUID将使用当前运行时配置下支持的最高叶报告。
此外,所讨论的MSR标志在当前(2014年6月)的英特尔®64和IA-32架构软件开发人员手册中称为“IA32_MISC_ENABLE.BOOT_NT4 [bit 22]”。我怀疑他们决定在某个时候将其重命名,以使其更加明显,这是一个现在可以安全忽略的遗留问题。