00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <arch/cpu.h>
00036 #include <arch/cpuid.h>
00037 #include <arch/pm.h>
00038
00039 #include <arch.h>
00040 #include <arch/types.h>
00041 #include <print.h>
00042 #include <typedefs.h>
00043 #include <fpu_context.h>
00044
00045 #include <arch/smp/apic.h>
00046
00047
00048
00049
00050
00051 #define AMD_CPUID_EBX 0x68747541
00052 #define AMD_CPUID_ECX 0x444d4163
00053 #define AMD_CPUID_EDX 0x69746e65
00054
00055 #define INTEL_CPUID_EBX 0x756e6547
00056 #define INTEL_CPUID_ECX 0x6c65746e
00057 #define INTEL_CPUID_EDX 0x49656e69
00058
00059
00060 enum vendor {
00061 VendorUnknown=0,
00062 VendorAMD,
00063 VendorIntel
00064 };
00065
00066 static char *vendor_str[] = {
00067 "Unknown Vendor",
00068 "AuthenticAMD",
00069 "GenuineIntel"
00070 };
00071
00072 void fpu_disable(void)
00073 {
00074 __asm__ volatile (
00075 "mov %%cr0,%%eax;"
00076 "or $8,%%eax;"
00077 "mov %%eax,%%cr0;"
00078 :
00079 :
00080 :"%eax"
00081 );
00082 }
00083
00084 void fpu_enable(void)
00085 {
00086 __asm__ volatile (
00087 "mov %%cr0,%%eax;"
00088 "and $0xffFFffF7,%%eax;"
00089 "mov %%eax,%%cr0;"
00090 :
00091 :
00092 :"%eax"
00093 );
00094 }
00095
00096 void cpu_arch_init(void)
00097 {
00098 cpuid_feature_info fi;
00099 cpuid_extended_feature_info efi;
00100 cpu_info_t info;
00101 __u32 help = 0;
00102
00103 CPU->arch.tss = tss_p;
00104 CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((__u8 *) CPU->arch.tss);
00105
00106 CPU->fpu_owner = NULL;
00107
00108 cpuid(1, &info);
00109
00110 fi.word = info.cpuid_edx;
00111 efi.word = info.cpuid_ecx;
00112
00113 if (fi.bits.fxsr)
00114 fpu_fxsr();
00115 else
00116 fpu_fsr();
00117
00118 if (fi.bits.sse) {
00119 asm volatile (
00120 "mov %%cr4,%0\n"
00121 "or %1,%0\n"
00122 "mov %0,%%cr4\n"
00123 : "+r" (help)
00124 : "i" (CR4_OSFXSR_MASK|(1<<10))
00125 );
00126 }
00127 }
00128
00129 void cpu_identify(void)
00130 {
00131 cpu_info_t info;
00132
00133 CPU->arch.vendor = VendorUnknown;
00134 if (has_cpuid()) {
00135 cpuid(0, &info);
00136
00137
00138
00139
00140 if (info.cpuid_ebx==AMD_CPUID_EBX && info.cpuid_ecx==AMD_CPUID_ECX && info.cpuid_edx==AMD_CPUID_EDX) {
00141 CPU->arch.vendor = VendorAMD;
00142 }
00143
00144
00145
00146
00147 if (info.cpuid_ebx==INTEL_CPUID_EBX && info.cpuid_ecx==INTEL_CPUID_ECX && info.cpuid_edx==INTEL_CPUID_EDX) {
00148 CPU->arch.vendor = VendorIntel;
00149 }
00150
00151 cpuid(1, &info);
00152 CPU->arch.family = (info.cpuid_eax>>8)&0xf;
00153 CPU->arch.model = (info.cpuid_eax>>4)&0xf;
00154 CPU->arch.stepping = (info.cpuid_eax>>0)&0xf;
00155 }
00156 }
00157
00158 void cpu_print_report(cpu_t* m)
00159 {
00160 printf("cpu%d: (%s family=%d model=%d stepping=%d) %dMHz\n",
00161 m->id, vendor_str[m->arch.vendor], m->arch.family, m->arch.model, m->arch.stepping,
00162 m->frequency_mhz);
00163 }
00164