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 /*
00046  * Identification of CPUs.
00047  * Contains only non-MP-Specification specific SMP code.
00048  */
00049 #define AMD_CPUID_EBX   0x68747541
00050 #define AMD_CPUID_ECX   0x444d4163
00051 #define AMD_CPUID_EDX   0x69746e65
00052 
00053 #define INTEL_CPUID_EBX 0x756e6547
00054 #define INTEL_CPUID_ECX 0x6c65746e
00055 #define INTEL_CPUID_EDX 0x49656e69
00056 
00057 
00058 enum vendor {
00059         VendorUnknown=0,
00060         VendorAMD,
00061         VendorIntel
00062 };
00063 
00064 static char *vendor_str[] = {
00065         "Unknown Vendor",
00066         "AuthenticAMD",
00067         "GenuineIntel"
00068 };
00069 
00070 
00077 void cpu_setup_fpu(void)
00078 {
00079         __asm__ volatile (
00080                 "movq %%cr0, %%rax;"
00081                 "btsq $1, %%rax;" /* cr0.mp */
00082                 "btrq $2, %%rax;"  /* cr0.em */
00083                 "movq %%rax, %%cr0;"
00084 
00085                 "movq %%cr4, %%rax;"
00086                 "bts $9, %%rax;" /* cr4.osfxsr */
00087                 "movq %%rax, %%cr4;"
00088                 :
00089                 :
00090                 :"%rax"
00091                 );
00092 }
00093 
00100 void fpu_disable(void)
00101 {
00102         __asm__ volatile (
00103                 "mov %%cr0,%%rax;"
00104                 "bts $3,%%rax;"
00105                 "mov %%rax,%%cr0;"
00106                 :
00107                 :
00108                 :"%rax"
00109                 );
00110 }
00111 
00112 void fpu_enable(void)
00113 {
00114         __asm__ volatile (
00115                 "mov %%cr0,%%rax;"
00116                 "btr $3,%%rax;"
00117                 "mov %%rax,%%cr0;"
00118                 :
00119                 :
00120                 :"%rax"
00121                 );      
00122 }
00123 
00124 void cpu_arch_init(void)
00125 {
00126         CPU->arch.tss = tss_p;
00127         CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((__u8 *) CPU->arch.tss);
00128         CPU->fpu_owner = NULL;
00129 }
00130 
00131 void cpu_identify(void)
00132 {
00133         cpu_info_t info;
00134 
00135         CPU->arch.vendor = VendorUnknown;
00136         if (has_cpuid()) {
00137                 cpuid(0, &info);
00138 
00139                 /*
00140                  * Check for AMD processor.
00141                  */
00142                 if (info.cpuid_ebx==AMD_CPUID_EBX && info.cpuid_ecx==AMD_CPUID_ECX && info.cpuid_edx==AMD_CPUID_EDX) {
00143                         CPU->arch.vendor = VendorAMD;
00144                 }
00145 
00146                 /*
00147                  * Check for Intel processor.
00148                  */             
00149                 if (info.cpuid_ebx==INTEL_CPUID_EBX && info.cpuid_ecx==INTEL_CPUID_ECX && info.cpuid_edx==INTEL_CPUID_EDX) {
00150                         CPU->arch.vendor = VendorIntel;
00151                 }
00152                                 
00153                 cpuid(1, &info);
00154                 CPU->arch.family = (info.cpuid_eax>>8)&0xf;
00155                 CPU->arch.model = (info.cpuid_eax>>4)&0xf;
00156                 CPU->arch.stepping = (info.cpuid_eax>>0)&0xf;                                           
00157         }
00158 }
00159 
00160 void cpu_print_report(cpu_t* m)
00161 {
00162         printf("cpu%d: (%s family=%d model=%d stepping=%d) %dMHz\n",
00163                 m->id, vendor_str[m->arch.vendor], m->arch.family, m->arch.model, m->arch.stepping,
00164                 m->frequency_mhz);
00165 }
00166 

Generated on Sun Jun 18 16:26:57 2006 for HelenOS Kernel (amd64) by  doxygen 1.4.6