Phoenix
Object-oriented orthogonally persistent operating system
md_cpu_caps.h
Go to the documentation of this file.
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               &regs[RES_EAX], &regs[RES_EBX], &regs[RES_ECX], &regs[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_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines