加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactos操作系统实现(19)

发布时间:2020-12-15 05:02:27 所属栏目:百科 来源:网络整理
导读:由于 CPU 是多种多样,具备能力也是不一样的,并且不同厂家都会创新不同的功能。下面就来了解 CPU 特征识别,如下: /* Get the processor features for the CPU */ FeatureBits = KiGetFeatureBits(); 这里是通过函数 KiGetFeatureBits 来获取 CPU 特征位,
由于 CPU 是多种多样,具备能力也是不一样的,并且不同厂家都会创新不同的功能。下面就来了解 CPU 特征识别,如下:

/* Get the processor features for the CPU */

FeatureBits = KiGetFeatureBits();

这里是通过函数KiGetFeatureBits来获取CPU特征位,它的代码如下:

#001 ULONG

#002 NTAPI

#003 KiGetFeatureBits(VOID)

#004 {

#005 PKPRCB Prcb = KeGetCurrentPrcb();

获取当前处理器控制块。

#006 ULONG Vendor;

#007 ULONG FeatureBits = KF_WORKING_PTE;

初始化为允许分页管理。

#008 ULONG Reg[4];

#009 BOOLEAN ExtendedCPUID = TRUE;

#010 ULONG CpuFeatures = 0;

#011

#012 /* Get the Vendor ID */

#013 Vendor = KiGetCpuVendor();

获取厂家标识。

#014

#015 /* Make sure we got a valid vendor ID at least. */

#016 if (!Vendor) return FeatureBits;

如果不认识的厂家CPU,就不用去获取特征了。

#017

#018 /* Get the CPUID Info. Features are in Reg[3]. */

#019 CPUID(Reg,1);

获取CPUID信息。

#020

#021 /* Set the initial APIC ID */

#022 Prcb->InitialApicId = (UCHAR)(Reg[1] >> 24);

设置APICAdvanced Programmable Interrupt Controller)的ID

#023

根据不同的厂家处理。

#024 switch (Vendor)

#025 {

下面是INTELCPU特性识别。

#026 /* Intel CPUs */

#027 case CPU_INTEL:

#028 /* Check if it's a P6 */

#029 if (Prcb->CpuType == 6)

#030 {

#031 /* Perform the special sequence to get the MicroCode Signature */

#032 WRMSR(0x8B,0);

#033 CPUID(Reg,1);

#034 Prcb->UpdateSignature.QuadPart = RDMSR(0x8B);

#035 }

#036 else if (Prcb->CpuType == 5)

#037 {

#038 /* On P5,enable workaround for the LOCK errata. */

#039 KiI386PentiumLockErrataPresent = TRUE;

#040 }

#041

#042 /* Check for broken P6 with bad SMP PTE implementation */

#043 if (((Reg[0] & 0x0FF0) == 0x0610 && (Reg[0] & 0x 000F ) <= 0x9) ||

#044 ((Reg[0] & 0x0FF0) == 0x0630 && (Reg[0] & 0x 000F ) <= 0x4))

#045 {

#046 /* Remove support for correct PTE support. */

#047 FeatureBits &= ~KF_WORKING_PTE;

#048 }

#049

#050 /* Check if the CPU is too old to support SYSENTER */

#051 if ((Prcb->CpuType < 6) ||

#052 ((Prcb->CpuType == 6) && (Prcb->CpuStep < 0x0303)))

#053 {

#054 /* Disable it */

#055 Reg[3] &= ~0x800;

#056 }

#057

#058 /* Set the current features */

#059 CpuFeatures = Reg[3];

#060

#061 break;

#062

下面AMDCPU特性识别处理。

#063 /* AMD CPUs */

#064 case CPU_AMD:

#065

#066 /* Check if this is a K5 or K6. (family 5) */

#067 if ((Reg[0] & 0x 0F 00) == 0x0500)

#068 {

#069 /* Get the Model Number */

#070 switch (Reg[0] & 0x 00F 0)

#071 {

#072 /* Model 1: K5 - 5k86 (initial models) */

#073 case 0x0010:

#074

#075 /* Check if this is Step 0 or 1. They don't support PGE */

#076 if ((Reg[0] & 0x 000F ) > 0x03) break;

#077

#078 /* Model 0: K5 - SSA5 */

#079 case 0x0000:

#080

#081 /* Model 0 doesn't support PGE at all. */

#082 Reg[3] &= ~0x2000;

#083 break;

#084

#085 /* Model 8: K6-2 */

#086 case 0x0080:

#087

#088 /* K6-2,Step 8 and over have support for MTRR. */

#089 if ((Reg[0] & 0x 000F ) >= 0x8) FeatureBits |= KF_AMDK6MTRR;

#090 break;

#091

#092 /* Model 9: K6-III

#093 Model D: K6-2+,K6-III+ */

#094 case 0x0090:

#095 case 0x00D0:

#096

#097 FeatureBits |= KF_AMDK6MTRR;

#098 break;

#099 }

#100 }

#101 else if((Reg[0] & 0x 0F 00) < 0x0500)

#102 {

#103 /* Families below 5 don't support PGE,PSE or CMOV at all */

#104 Reg[3] &= ~(0x08 | 0x2000 | 0x8000);

#105

#106 /* They also don't support advanced CPUID functions. */

#107 ExtendedCPUID = FALSE;

#108 }

#109

#110 /* Set the current features */

#111 CpuFeatures = Reg[3];

#112

#113 break;

#114

其它X86CPU还没有处理。

#115 /* Cyrix CPUs */

#116 case CPU_CYRIX:

#117 break;

#118

#119 /* Transmeta CPUs */

#120 case CPU_TRANSMETA:

#121 /* Enable CMPXCHG8B if the family (>= 5),model and stepping (>= 4.2) support it */

#122 if ((Reg[0] & 0x0FFF) >= 0x0542)

#123 {

#124 WRMSR(0x80860004,RDMSR(0x80860004) | 0x0100);

#125 FeatureBits |= KF_CMPXCHG8B;

#126 }

#127

#128 break;

#129

#130 /* Centaur,IDT,Rise and VIA CPUs */

#131 case CPU_CENTAUR:

#132 case CPU_RISE:

#133 /* These CPUs don't report the presence of CMPXCHG8B through CPUID.

#134 However,this feature exists and operates properly without any additional steps. */

#135 FeatureBits |= KF_CMPXCHG8B;

#136

#137 break;

#138 }

#139

转换CPUID为内核使用的标识。

#140 /* Convert all CPUID Feature bits into our format */

#141 if (CpuFeatures & 0x00000002) FeatureBits |= KF_V86_VIS | KF_CR4;

#142 if (CpuFeatures & 0x00000008) FeatureBits |= KF_LARGE_PAGE | KF_CR4;

#143 if (CpuFeatures & 0x00000010) FeatureBits |= KF_RDTSC;

#144 if (CpuFeatures & 0x00000100) FeatureBits |= KF_CMPXCHG8B;

#145 if (CpuFeatures & 0x00000800) FeatureBits |= KF_FAST_SYSCALL;

#146 if (CpuFeatures & 0x00001000) FeatureBits |= KF_MTRR;

#147 if (CpuFeatures & 0x00002000) FeatureBits |= KF_GLOBAL_PAGE | KF_CR4;

#148 if (CpuFeatures & 0x00008000) FeatureBits |= KF_CMOV;

#149 if (CpuFeatures & 0x00010000) FeatureBits |= KF_PAT;

#150 if (CpuFeatures & 0x00200000) FeatureBits |= KF_DTS;

#151 if (CpuFeatures & 0x00800000) FeatureBits |= KF_MMX;

#152 if (CpuFeatures & 0x01000000) FeatureBits |= KF_FXSR;

#153 if (CpuFeatures & 0x02000000) FeatureBits |= KF_XMMI;

#154 if (CpuFeatures & 0x04000000) FeatureBits |= KF_XMMI64;

#155

检查CPU是否具有超线程。

#156 /* Check if the CPU has hyper-threading */

#157 if (CpuFeatures & 0x10000000)

#158 {

#159 /* Set the number of logical CPUs */

#160 Prcb->LogicalProcessorsPerPhysicalProcessor = (UCHAR)(Reg[1] >> 16);

#161 if (Prcb->LogicalProcessorsPerPhysicalProcessor > 1)

#162 {

#163 /* We're on dual-core */

#164 KiSMTProcessorsPresent = TRUE;

#165 }

#166 }

#167 else

#168 {

#169 /* We only have a single CPU */

#170 Prcb->LogicalProcessorsPerPhysicalProcessor = 1;

#171 }

#172

#173 /* Check if CPUID 0x80000000 is supported */

#174 if (ExtendedCPUID)

#175 {

#176 /* Do the call */

#177 CPUID(Reg,0x80000000);

#178 if ((Reg[0] & 0xffffff00) == 0x80000000)

#179 {

#180 /* Check if CPUID 0x80000001 is supported */

#181 if (Reg[0] >= 0x80000001)

#182 {

#183 /* Check which extended features are available. */

#184 CPUID(Reg,0x80000001);

#185

#186 /* Check if NX-bit is supported */

#187 if (Reg[3] & 0x00100000) FeatureBits |= KF_NX_BIT;

#188

#189 /* Now handle each features for each CPU Vendor */

#190 switch (Vendor)

#191 {

#192 case CPU_AMD:

#193 case CPU_CENTAUR:

#194 if (Reg[3] & 0x80000000) FeatureBits |= KF_3DNOW;

#195 break;

#196 }

#197 }

#198 }

#199 }

#200

#201 /* Return the Feature Bits */

#202 return FeatureBits;

#203 }

现在看看什么是APICAPIC (高级可编程中断控制器)对计算机来讲有两个作用,

一是管理IRQ的分配,可以把传统的16IRQ扩展到24个(传统的管理方式叫PIC),以适应更多的设备。

二是管理多CPU

不过,如果板卡不是非常多的话,关闭 APIC对系统是没有什么影响的。

要实现SMP功能,我们使用的CPU必须具备以下要求:

CPU内部必须内置APIC单元。Intel 多处理规范的核心就是高级可编程中断控制器(Advanced Programmable Interrupt ControllersAPICs)的使用。CPU通过彼此发送中断来完成它们之间的通信。通过给中断附加动作(actions),不同的CPU可以在某种程度上彼此进行控制。每个CPU有自己的APIC(成为那个CPU的本地APIC),并且还有一个I/O APIC来处理由I/O设备引起的中断,这个I/O APIC是安装在主板上的,但每个CPU上的APIC则不可或缺,否则将无法处理多CPU之间的中断协调。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读