Subversion Repositories HelenOS

Rev

Rev 3492 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2001-2004 Jakub Jermar
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup ia32
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #include <arch/cpu.h>
  36. #include <arch/cpuid.h>
  37. #include <arch/pm.h>
  38.  
  39. #include <arch.h>
  40. #include <arch/types.h>
  41. #include <print.h>
  42. #include <fpu_context.h>
  43.  
  44. #include <arch/smp/apic.h>
  45. #include <arch/syscall.h>
  46.  
  47. /*
  48.  * Identification of CPUs.
  49.  * Contains only non-MP-Specification specific SMP code.
  50.  */
  51. #define AMD_CPUID_EBX   0x68747541
  52. #define AMD_CPUID_ECX   0x444d4163
  53. #define AMD_CPUID_EDX   0x69746e65
  54.  
  55. #define INTEL_CPUID_EBX 0x756e6547
  56. #define INTEL_CPUID_ECX 0x6c65746e
  57. #define INTEL_CPUID_EDX 0x49656e69
  58.  
  59.  
  60. enum vendor {
  61.     VendorUnknown=0,
  62.     VendorAMD,
  63.     VendorIntel
  64. };
  65.  
  66. static char *vendor_str[] = {
  67.     "Unknown Vendor",
  68.     "AMD",
  69.     "Intel"
  70. };
  71.  
  72. void fpu_disable(void)
  73. {
  74.     asm volatile (
  75.         "mov %%cr0,%%eax;"
  76.         "or $8,%%eax;"
  77.         "mov %%eax,%%cr0;"
  78.         :
  79.         :
  80.         : "%eax"
  81.     );
  82. }
  83.  
  84. void fpu_enable(void)
  85. {
  86.     asm volatile (
  87.         "mov %%cr0,%%eax;"
  88.         "and $0xffFFffF7,%%eax;"
  89.         "mov %%eax,%%cr0;"
  90.         :
  91.         :
  92.         : "%eax"
  93.     ); 
  94. }
  95.  
  96. void cpu_arch_init(void)
  97. {
  98.     cpuid_feature_info fi;
  99.     cpuid_extended_feature_info efi;
  100.     cpu_info_t info;
  101.     uint32_t help = 0;
  102.    
  103.     CPU->arch.tss = tss_p;
  104.     CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((uint8_t *) CPU->arch.tss);
  105.  
  106.     CPU->fpu_owner = NULL;
  107.  
  108.     cpuid(1, &info);
  109.  
  110.     fi.word = info.cpuid_edx;
  111.     efi.word = info.cpuid_ecx;
  112.    
  113.     if (fi.bits.fxsr)
  114.         fpu_fxsr();
  115.     else
  116.         fpu_fsr(); 
  117.    
  118.     if (fi.bits.sse) {
  119.         asm volatile (
  120.             "mov %%cr4,%0\n"
  121.             "or %1,%0\n"
  122.             "mov %0,%%cr4\n"
  123.             : "+r" (help)
  124.             : "i" (CR4_OSFXSR_MASK|(1<<10))
  125.         );
  126.     }
  127.    
  128.     /* Setup fast SYSENTER/SYSEXIT syscalls */
  129.     syscall_setup_cpu();
  130. }
  131.  
  132. void cpu_identify(void)
  133. {
  134.     cpu_info_t info;
  135.  
  136.     CPU->arch.vendor = VendorUnknown;
  137.     if (has_cpuid()) {
  138.         cpuid(0, &info);
  139.  
  140.         /*
  141.          * Check for AMD processor.
  142.          */
  143.         if ((info.cpuid_ebx == AMD_CPUID_EBX)
  144.             && (info.cpuid_ecx == AMD_CPUID_ECX)
  145.             && (info.cpuid_edx == AMD_CPUID_EDX))
  146.             CPU->arch.vendor = VendorAMD;
  147.        
  148.         /*
  149.          * Check for Intel processor.
  150.          */    
  151.         if ((info.cpuid_ebx == INTEL_CPUID_EBX)
  152.             && (info.cpuid_ecx == INTEL_CPUID_ECX)
  153.             && (info.cpuid_edx == INTEL_CPUID_EDX))
  154.             CPU->arch.vendor = VendorIntel;
  155.        
  156.         cpuid(1, &info);
  157.         CPU->arch.family = (info.cpuid_eax >> 8) & 0x0f;
  158.         CPU->arch.model = (info.cpuid_eax >> 4) & 0x0f;
  159.         CPU->arch.stepping = (info.cpuid_eax >> 0) & 0x0f;                     
  160.     }
  161. }
  162.  
  163. void cpu_print_report(cpu_t* cpu)
  164. {
  165.     printf("cpu%u: (%s family=%u model=%u stepping=%u) %" PRIu16 " MHz\n",
  166.         cpu->id, vendor_str[cpu->arch.vendor], cpu->arch.family,
  167.         cpu->arch.model, cpu->arch.stepping, cpu->frequency_mhz);
  168. }
  169.  
  170. /** @}
  171.  */
  172.