00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "src/common/shared.hpp"
00018 #include "src/tty/teletype.hpp"
00019 #include "src/memory/heap.hpp"
00020 #include "src/common/string.hpp"
00021 #include "src/arch/x86/interr.hpp"
00022 #include "src/arch/x86/except_c.hpp"
00023 #include "src/arch/x86/cpuid.hpp"
00024
00025
00026
00027 namespace Arch {
00028 namespace x86 {
00029
00030
00031 uint32 volatile cpuid_failure = 0;
00032 uint32 volatile cpuid_success=0;
00033 char cpu_vendor_name [13];
00034 uint32 cpu_flags=0;
00035 uint32 cpu_signature;
00036
00037
00038 void init()
00039 {
00040
00041 if (check_cpuid() != ESUCCESS)
00042 sysfail ("no cpuid instruction!");
00043
00044 uint32 max;
00045 uint32 a;
00046
00047 cpuid(0,&max,(uint32*)cpu_vendor_name,((uint32*)cpu_vendor_name)+2,((uint32*)cpu_vendor_name)+1);
00048 cpu_vendor_name[12]=0;
00049 cout("CPUID: ");
00050 cout(cpu_vendor_name);
00051 cout("; ");
00052
00053 cpuid(1, &cpu_signature, &a, &a, &cpu_flags);
00054
00055 if (cpu_flags & CPU_SEP)
00056 {
00057
00058 string str;
00059 str.set(cpu_vendor_name);
00060 if (str.strcmp("GenuineIntel"))
00061 if ((cpu_signature & 0x0FFF3FFF) < 0x00000633)
00062 sysfail ("!!!!!!!!!!sysenter/sysexit not availlable!(0)!!!!!!!!!!");
00063 cout("SYSENTER/SYSEXIT; ");
00064 str.inval();
00065 }
00066 else
00067 sysfail("!!!!!!!!!!!!!!sysenter/sysexit not availlable!(1)");
00068
00069 if (cpu_flags & CPU_TCS)
00070 cout("TIME-STAMP COUNTER; ");
00071 else sysfail("!!time-stamp counter not availlable");
00072
00073 cpuid_success=1;
00074 cout("\n");
00075 }
00076
00077
00078 void cpuid(uint32 input, uint32 *eax, uint32 *ebx, uint32 *ecx, uint32 *edx)
00079 {
00080
00081 asm volatile ("cpuid" : "=d" (*edx), "=a" (*eax), "=b" (*ebx), "=c" (*ecx) : "a" (input));
00082 }
00083
00084
00085 int cpuid_isr(Interr::except2_t *code)
00086 {
00087 uint32 *word;
00088
00089 cpuid_failure = 1;
00090
00091 word = (uint32*) code->eip;
00092 (*word) = 0x9090;
00093
00094 return ESUCCESS;
00095 }
00096
00097
00098 int check_cpuid()
00099 {
00100 uint32 handle;
00101
00102 uint32 fl;
00103 asm volatile ("pushf\npopl %0\ncli" : "=g" (fl) );
00104
00105 handle= add2interr_chain(Interr::INT_OPCODE, &cpuid_isr);
00106 asm volatile ("cpuid" : : "a" (0) );
00107
00108 Interr::del_chainHdl(Interr::INT_OPCODE, handle);
00109
00110 asm volatile ("pushl %0\npopf" : : "g" (fl));
00111
00112 if (cpuid_failure)
00113 return EINVAL;
00114
00115 return ESUCCESS;
00116 }
00117
00118
00119 };
00120 };
00121
00122
00123
00124
00125
00126
00127
00128