cpu.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2004 Jakub Jermar
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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  * Identification of CPUs.
00049  * Contains only non-MP-Specification specific SMP code.
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                  * Check for AMD processor.
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                  * Check for Intel processor.
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 

Generated on Sun Jun 18 16:38:51 2006 for HelenOS Kernel (ia32) by  doxygen 1.4.6