Phoenix
Object-oriented orthogonally persistent operating system
|
00001 /* 00002 * /phoenix/kernel/sys/arch/x86_64/md_cpu_caps.h 00003 * 00004 * This file is a part of Phoenix operating system. 00005 * Copyright (c) 2011-2012, Artyom Lebedev <artyom.lebedev@gmail.com> 00006 * All rights reserved. 00007 * See COPYING file for copyright details. 00008 */ 00009 00015 #ifndef MD_CPU_CAPS_H_ 00016 #define MD_CPU_CAPS_H_ 00017 00018 #ifdef AUTONOMOUS_LINKING 00019 namespace { 00020 #endif /* AUTONOMOUS_LINKING */ 00021 00022 namespace cpu { 00023 00025 class CpuCaps { 00026 public: 00034 unsigned long GetCapability(CpuCapId cap) { 00035 if (cap >= CPU_CAP_MAX) { 00036 return 0; 00037 } 00038 if (cap == CPU_CAP_NONE) { 00039 return CPU_CAP_MAX; 00040 } 00041 00042 FeatureDesc feature; 00043 if (!MapCapability(cap, &feature)) { 00044 return 0; 00045 } 00046 00047 u32 maxFeature, maxExtFeature; 00048 cpuid(0, 0, &maxFeature, 0, 0, 0); 00049 cpuid(EXT_FEAT_BASE, 0, &maxExtFeature, 0, 0, 0); 00050 00051 if ((feature.cpuidFeatureId < EXT_FEAT_BASE && feature.cpuidFeatureId > maxFeature) || 00052 (feature.cpuidFeatureId >= EXT_FEAT_BASE && feature.cpuidFeatureId > maxExtFeature)) { 00053 /* The feature is not present in this CPU. */ 00054 return feature.defValue; 00055 } 00056 00057 u32 regs[RES_MAX]; 00058 cpuid(feature.cpuidFeatureId, feature.cpuidFeatureSubid, 00059 ®s[RES_EAX], ®s[RES_EBX], ®s[RES_ECX], ®s[RES_EDX]); 00060 00061 return (regs[feature.resultReg] >> feature.bitIdx) & 00062 ((1 << feature.numBits) - 1); 00063 } 00064 00065 private: 00066 enum CpuidResultReg { 00067 RES_EAX, 00068 RES_EBX, 00069 RES_ECX, 00070 RES_EDX, 00071 RES_MAX 00072 }; 00073 00074 enum { 00075 EXT_FEAT_BASE = 0x80000000 00076 }; 00077 00078 struct FeatureDesc { 00079 CpuCapId cap; 00080 long cpuidFeatureId, cpuidFeatureSubid; 00081 CpuidResultReg resultReg; 00082 int bitIdx, numBits; 00083 unsigned long defValue; 00084 }; 00085 00086 bool MapCapability(CpuCapId cap, FeatureDesc *feat) { 00087 static FeatureDesc features[] = { 00088 { CPU_CAP_PG_PGE, 0x1, 0, RES_EDX, 13, 1, 0 }, 00089 { CPU_CAP_PG_PAT, 0x1, 0, RES_EDX, 16, 1, 0 }, 00090 { CPU_CAP_PG_PCID, 0x1, 0, RES_ECX, 17, 1, 0 }, 00091 { CPU_CAP_PG_SMEP, 0x7, 0, RES_EBX, 7, 1, 0 }, 00092 { CPU_CAP_PG_NX, 0x80000001, 0, RES_EDX, 20, 1, 0 }, 00093 { CPU_CAP_PG_1GB, 80000001, 0, RES_EDX, 26, 1, 0 }, 00094 { CPU_CAP_PG_WIDTH_PHYS, 0x80000008, 0, RES_EAX, 0, 8, 36 }, 00095 { CPU_CAP_PG_WIDTH_LIN, 0x80000008, 0, RES_EAX, 8, 8, 32 }, 00096 }; 00097 00098 for (auto &feature: features) { 00099 if (feature.cap == cap) { 00100 *feat = feature; 00101 return true; 00102 } 00103 } 00104 return false; 00105 } 00106 }; 00107 00108 } /* namespace cpu */ 00109 00110 #ifdef AUTONOMOUS_LINKING 00111 } 00112 #endif /* AUTONOMOUS_LINKING */ 00113 00114 #endif /* MD_CPU_CAPS_H_ */