The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/i386/initcpu.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) KATO Takenori, 1997, 1998.
    3  * 
    4  * All rights reserved.  Unpublished rights reserved under the copyright
    5  * laws of Japan.
    6  * 
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer as
   13  *    the first lines of this file unmodified.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD: releng/11.0/sys/i386/i386/initcpu.c 292668 2015-12-23 21:41:42Z jhb $");
   32 
   33 #include "opt_cpu.h"
   34 
   35 #include <sys/param.h>
   36 #include <sys/kernel.h>
   37 #include <sys/systm.h>
   38 #include <sys/sysctl.h>
   39 
   40 #include <machine/cputypes.h>
   41 #include <machine/md_var.h>
   42 #include <machine/specialreg.h>
   43 
   44 #include <vm/vm.h>
   45 #include <vm/pmap.h>
   46 
   47 #if !defined(CPU_DISABLE_SSE) && defined(I686_CPU)
   48 #define CPU_ENABLE_SSE
   49 #endif
   50 
   51 #ifdef I486_CPU
   52 static void init_5x86(void);
   53 static void init_bluelightning(void);
   54 static void init_486dlc(void);
   55 static void init_cy486dx(void);
   56 #ifdef CPU_I486_ON_386
   57 static void init_i486_on_386(void);
   58 #endif
   59 static void init_6x86(void);
   60 #endif /* I486_CPU */
   61 
   62 #if defined(I586_CPU) && defined(CPU_WT_ALLOC)
   63 static void     enable_K5_wt_alloc(void);
   64 static void     enable_K6_wt_alloc(void);
   65 static void     enable_K6_2_wt_alloc(void);
   66 #endif
   67 
   68 #ifdef I686_CPU
   69 static void     init_6x86MX(void);
   70 static void     init_ppro(void);
   71 static void     init_mendocino(void);
   72 #endif
   73 
   74 static int      hw_instruction_sse;
   75 SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD,
   76     &hw_instruction_sse, 0, "SIMD/MMX2 instructions available in CPU");
   77 /*
   78  * -1: automatic (default)
   79  *  0: keep enable CLFLUSH
   80  *  1: force disable CLFLUSH
   81  */
   82 static int      hw_clflush_disable = -1;
   83 
   84 u_int   cyrix_did;              /* Device ID of Cyrix CPU */
   85 
   86 #ifdef I486_CPU
   87 /*
   88  * IBM Blue Lightning
   89  */
   90 static void
   91 init_bluelightning(void)
   92 {
   93         register_t saveintr;
   94 
   95 #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
   96         need_post_dma_flush = 1;
   97 #endif
   98 
   99         saveintr = intr_disable();
  100 
  101         load_cr0(rcr0() | CR0_CD | CR0_NW);
  102         invd();
  103 
  104 #ifdef CPU_BLUELIGHTNING_FPU_OP_CACHE
  105         wrmsr(0x1000, 0x9c92LL);        /* FP operand can be cacheable on Cyrix FPU */
  106 #else
  107         wrmsr(0x1000, 0x1c92LL);        /* Intel FPU */
  108 #endif
  109         /* Enables 13MB and 0-640KB cache. */
  110         wrmsr(0x1001, (0xd0LL << 32) | 0x3ff);
  111 #ifdef CPU_BLUELIGHTNING_3X
  112         wrmsr(0x1002, 0x04000000LL);    /* Enables triple-clock mode. */
  113 #else
  114         wrmsr(0x1002, 0x03000000LL);    /* Enables double-clock mode. */
  115 #endif
  116 
  117         /* Enable caching in CR0. */
  118         load_cr0(rcr0() & ~(CR0_CD | CR0_NW));  /* CD = 0 and NW = 0 */
  119         invd();
  120         intr_restore(saveintr);
  121 }
  122 
  123 /*
  124  * Cyrix 486SLC/DLC/SR/DR series
  125  */
  126 static void
  127 init_486dlc(void)
  128 {
  129         register_t saveintr;
  130         u_char  ccr0;
  131 
  132         saveintr = intr_disable();
  133         invd();
  134 
  135         ccr0 = read_cyrix_reg(CCR0);
  136 #ifndef CYRIX_CACHE_WORKS
  137         ccr0 |= CCR0_NC1 | CCR0_BARB;
  138         write_cyrix_reg(CCR0, ccr0);
  139         invd();
  140 #else
  141         ccr0 &= ~CCR0_NC0;
  142 #ifndef CYRIX_CACHE_REALLY_WORKS
  143         ccr0 |= CCR0_NC1 | CCR0_BARB;
  144 #else
  145         ccr0 |= CCR0_NC1;
  146 #endif
  147 #ifdef CPU_DIRECT_MAPPED_CACHE
  148         ccr0 |= CCR0_CO;                        /* Direct mapped mode. */
  149 #endif
  150         write_cyrix_reg(CCR0, ccr0);
  151 
  152         /* Clear non-cacheable region. */
  153         write_cyrix_reg(NCR1+2, NCR_SIZE_0K);
  154         write_cyrix_reg(NCR2+2, NCR_SIZE_0K);
  155         write_cyrix_reg(NCR3+2, NCR_SIZE_0K);
  156         write_cyrix_reg(NCR4+2, NCR_SIZE_0K);
  157 
  158         write_cyrix_reg(0, 0);  /* dummy write */
  159 
  160         /* Enable caching in CR0. */
  161         load_cr0(rcr0() & ~(CR0_CD | CR0_NW));  /* CD = 0 and NW = 0 */
  162         invd();
  163 #endif /* !CYRIX_CACHE_WORKS */
  164         intr_restore(saveintr);
  165 }
  166 
  167 
  168 /*
  169  * Cyrix 486S/DX series
  170  */
  171 static void
  172 init_cy486dx(void)
  173 {
  174         register_t saveintr;
  175         u_char  ccr2;
  176 
  177         saveintr = intr_disable();
  178         invd();
  179 
  180         ccr2 = read_cyrix_reg(CCR2);
  181 #ifdef CPU_SUSP_HLT
  182         ccr2 |= CCR2_SUSP_HLT;
  183 #endif
  184 
  185 #ifdef PC98
  186         /* Enables WB cache interface pin and Lock NW bit in CR0. */
  187         ccr2 |= CCR2_WB | CCR2_LOCK_NW;
  188         /* Unlock NW bit in CR0. */
  189         write_cyrix_reg(CCR2, ccr2 & ~CCR2_LOCK_NW);
  190         load_cr0((rcr0() & ~CR0_CD) | CR0_NW);  /* CD = 0, NW = 1 */
  191 #endif
  192 
  193         write_cyrix_reg(CCR2, ccr2);
  194         intr_restore(saveintr);
  195 }
  196 
  197 
  198 /*
  199  * Cyrix 5x86
  200  */
  201 static void
  202 init_5x86(void)
  203 {
  204         register_t saveintr;
  205         u_char  ccr2, ccr3, ccr4, pcr0;
  206 
  207         saveintr = intr_disable();
  208 
  209         load_cr0(rcr0() | CR0_CD | CR0_NW);
  210         wbinvd();
  211 
  212         (void)read_cyrix_reg(CCR3);             /* dummy */
  213 
  214         /* Initialize CCR2. */
  215         ccr2 = read_cyrix_reg(CCR2);
  216         ccr2 |= CCR2_WB;
  217 #ifdef CPU_SUSP_HLT
  218         ccr2 |= CCR2_SUSP_HLT;
  219 #else
  220         ccr2 &= ~CCR2_SUSP_HLT;
  221 #endif
  222         ccr2 |= CCR2_WT1;
  223         write_cyrix_reg(CCR2, ccr2);
  224 
  225         /* Initialize CCR4. */
  226         ccr3 = read_cyrix_reg(CCR3);
  227         write_cyrix_reg(CCR3, CCR3_MAPEN0);
  228 
  229         ccr4 = read_cyrix_reg(CCR4);
  230         ccr4 |= CCR4_DTE;
  231         ccr4 |= CCR4_MEM;
  232 #ifdef CPU_FASTER_5X86_FPU
  233         ccr4 |= CCR4_FASTFPE;
  234 #else
  235         ccr4 &= ~CCR4_FASTFPE;
  236 #endif
  237         ccr4 &= ~CCR4_IOMASK;
  238         /********************************************************************
  239          * WARNING: The "BIOS Writers Guide" mentions that I/O recovery time
  240          * should be 0 for errata fix.
  241          ********************************************************************/
  242 #ifdef CPU_IORT
  243         ccr4 |= CPU_IORT & CCR4_IOMASK;
  244 #endif
  245         write_cyrix_reg(CCR4, ccr4);
  246 
  247         /* Initialize PCR0. */
  248         /****************************************************************
  249          * WARNING: RSTK_EN and LOOP_EN could make your system unstable.
  250          * BTB_EN might make your system unstable.
  251          ****************************************************************/
  252         pcr0 = read_cyrix_reg(PCR0);
  253 #ifdef CPU_RSTK_EN
  254         pcr0 |= PCR0_RSTK;
  255 #else
  256         pcr0 &= ~PCR0_RSTK;
  257 #endif
  258 #ifdef CPU_BTB_EN
  259         pcr0 |= PCR0_BTB;
  260 #else
  261         pcr0 &= ~PCR0_BTB;
  262 #endif
  263 #ifdef CPU_LOOP_EN
  264         pcr0 |= PCR0_LOOP;
  265 #else
  266         pcr0 &= ~PCR0_LOOP;
  267 #endif
  268 
  269         /****************************************************************
  270          * WARNING: if you use a memory mapped I/O device, don't use
  271          * DISABLE_5X86_LSSER option, which may reorder memory mapped
  272          * I/O access.
  273          * IF YOUR MOTHERBOARD HAS PCI BUS, DON'T DISABLE LSSER.
  274          ****************************************************************/
  275 #ifdef CPU_DISABLE_5X86_LSSER
  276         pcr0 &= ~PCR0_LSSER;
  277 #else
  278         pcr0 |= PCR0_LSSER;
  279 #endif
  280         write_cyrix_reg(PCR0, pcr0);
  281 
  282         /* Restore CCR3. */
  283         write_cyrix_reg(CCR3, ccr3);
  284 
  285         (void)read_cyrix_reg(0x80);             /* dummy */
  286 
  287         /* Unlock NW bit in CR0. */
  288         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
  289         load_cr0((rcr0() & ~CR0_CD) | CR0_NW);  /* CD = 0, NW = 1 */
  290         /* Lock NW bit in CR0. */
  291         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
  292 
  293         intr_restore(saveintr);
  294 }
  295 
  296 #ifdef CPU_I486_ON_386
  297 /*
  298  * There are i486 based upgrade products for i386 machines.
  299  * In this case, BIOS doesn't enable CPU cache.
  300  */
  301 static void
  302 init_i486_on_386(void)
  303 {
  304         register_t saveintr;
  305 
  306 #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
  307         need_post_dma_flush = 1;
  308 #endif
  309 
  310         saveintr = intr_disable();
  311 
  312         load_cr0(rcr0() & ~(CR0_CD | CR0_NW));  /* CD = 0, NW = 0 */
  313 
  314         intr_restore(saveintr);
  315 }
  316 #endif
  317 
  318 /*
  319  * Cyrix 6x86
  320  *
  321  * XXX - What should I do here?  Please let me know.
  322  */
  323 static void
  324 init_6x86(void)
  325 {
  326         register_t saveintr;
  327         u_char  ccr3, ccr4;
  328 
  329         saveintr = intr_disable();
  330 
  331         load_cr0(rcr0() | CR0_CD | CR0_NW);
  332         wbinvd();
  333 
  334         /* Initialize CCR0. */
  335         write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);
  336 
  337         /* Initialize CCR1. */
  338 #ifdef CPU_CYRIX_NO_LOCK
  339         write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK);
  340 #else
  341         write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK);
  342 #endif
  343 
  344         /* Initialize CCR2. */
  345 #ifdef CPU_SUSP_HLT
  346         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT);
  347 #else
  348         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT);
  349 #endif
  350 
  351         ccr3 = read_cyrix_reg(CCR3);
  352         write_cyrix_reg(CCR3, CCR3_MAPEN0);
  353 
  354         /* Initialize CCR4. */
  355         ccr4 = read_cyrix_reg(CCR4);
  356         ccr4 |= CCR4_DTE;
  357         ccr4 &= ~CCR4_IOMASK;
  358 #ifdef CPU_IORT
  359         write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK));
  360 #else
  361         write_cyrix_reg(CCR4, ccr4 | 7);
  362 #endif
  363 
  364         /* Initialize CCR5. */
  365 #ifdef CPU_WT_ALLOC
  366         write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC);
  367 #endif
  368 
  369         /* Restore CCR3. */
  370         write_cyrix_reg(CCR3, ccr3);
  371 
  372         /* Unlock NW bit in CR0. */
  373         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
  374 
  375         /*
  376          * Earlier revision of the 6x86 CPU could crash the system if
  377          * L1 cache is in write-back mode.
  378          */
  379         if ((cyrix_did & 0xff00) > 0x1600)
  380                 load_cr0(rcr0() & ~(CR0_CD | CR0_NW));  /* CD = 0 and NW = 0 */
  381         else {
  382                 /* Revision 2.6 and lower. */
  383 #ifdef CYRIX_CACHE_REALLY_WORKS
  384                 load_cr0(rcr0() & ~(CR0_CD | CR0_NW));  /* CD = 0 and NW = 0 */
  385 #else
  386                 load_cr0((rcr0() & ~CR0_CD) | CR0_NW);  /* CD = 0 and NW = 1 */
  387 #endif
  388         }
  389 
  390         /* Lock NW bit in CR0. */
  391         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
  392 
  393         intr_restore(saveintr);
  394 }
  395 #endif /* I486_CPU */
  396 
  397 #ifdef I586_CPU
  398 /*
  399  * Rise mP6
  400  */
  401 static void
  402 init_rise(void)
  403 {
  404 
  405         /*
  406          * The CMPXCHG8B instruction is always available but hidden.
  407          */
  408         cpu_feature |= CPUID_CX8;
  409 }
  410 
  411 /*
  412  * IDT WinChip C6/2/2A/2B/3
  413  *
  414  * http://www.centtech.com/winchip_bios_writers_guide_v4_0.pdf
  415  */
  416 static void
  417 init_winchip(void)
  418 {
  419         u_int regs[4];
  420         uint64_t fcr;
  421 
  422         fcr = rdmsr(0x0107);
  423 
  424         /*
  425          * Set ECX8, DSMC, DTLOCK/EDCTLB, EMMX, and ERETSTK and clear DPDC.
  426          */
  427         fcr |= (1 << 1) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 16);
  428         fcr &= ~(1ULL << 11);
  429 
  430         /*
  431          * Additionally, set EBRPRED, E2MMX and EAMD3D for WinChip 2 and 3.
  432          */
  433         if (CPUID_TO_MODEL(cpu_id) >= 8)
  434                 fcr |= (1 << 12) | (1 << 19) | (1 << 20);
  435 
  436         wrmsr(0x0107, fcr);
  437         do_cpuid(1, regs);
  438         cpu_feature = regs[3];
  439 }
  440 #endif
  441 
  442 #ifdef I686_CPU
  443 /*
  444  * Cyrix 6x86MX (code-named M2)
  445  *
  446  * XXX - What should I do here?  Please let me know.
  447  */
  448 static void
  449 init_6x86MX(void)
  450 {
  451         register_t saveintr;
  452         u_char  ccr3, ccr4;
  453 
  454         saveintr = intr_disable();
  455 
  456         load_cr0(rcr0() | CR0_CD | CR0_NW);
  457         wbinvd();
  458 
  459         /* Initialize CCR0. */
  460         write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);
  461 
  462         /* Initialize CCR1. */
  463 #ifdef CPU_CYRIX_NO_LOCK
  464         write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK);
  465 #else
  466         write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK);
  467 #endif
  468 
  469         /* Initialize CCR2. */
  470 #ifdef CPU_SUSP_HLT
  471         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT);
  472 #else
  473         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT);
  474 #endif
  475 
  476         ccr3 = read_cyrix_reg(CCR3);
  477         write_cyrix_reg(CCR3, CCR3_MAPEN0);
  478 
  479         /* Initialize CCR4. */
  480         ccr4 = read_cyrix_reg(CCR4);
  481         ccr4 &= ~CCR4_IOMASK;
  482 #ifdef CPU_IORT
  483         write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK));
  484 #else
  485         write_cyrix_reg(CCR4, ccr4 | 7);
  486 #endif
  487 
  488         /* Initialize CCR5. */
  489 #ifdef CPU_WT_ALLOC
  490         write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC);
  491 #endif
  492 
  493         /* Restore CCR3. */
  494         write_cyrix_reg(CCR3, ccr3);
  495 
  496         /* Unlock NW bit in CR0. */
  497         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
  498 
  499         load_cr0(rcr0() & ~(CR0_CD | CR0_NW));  /* CD = 0 and NW = 0 */
  500 
  501         /* Lock NW bit in CR0. */
  502         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
  503 
  504         intr_restore(saveintr);
  505 }
  506 
  507 static int ppro_apic_used = -1;
  508 
  509 static void
  510 init_ppro(void)
  511 {
  512         u_int64_t       apicbase;
  513 
  514         /*
  515          * Local APIC should be disabled if it is not going to be used.
  516          */
  517         if (ppro_apic_used != 1) {
  518                 apicbase = rdmsr(MSR_APICBASE);
  519                 apicbase &= ~APICBASE_ENABLED;
  520                 wrmsr(MSR_APICBASE, apicbase);
  521                 ppro_apic_used = 0;
  522         }
  523 }
  524 
  525 /*
  526  * If the local APIC is going to be used after being disabled above,
  527  * re-enable it and don't disable it in the future.
  528  */
  529 void
  530 ppro_reenable_apic(void)
  531 {
  532         u_int64_t       apicbase;
  533 
  534         if (ppro_apic_used == 0) {
  535                 apicbase = rdmsr(MSR_APICBASE);
  536                 apicbase |= APICBASE_ENABLED;
  537                 wrmsr(MSR_APICBASE, apicbase);
  538                 ppro_apic_used = 1;
  539         }
  540 }
  541 
  542 /*
  543  * Initialize BBL_CR_CTL3 (Control register 3: used to configure the
  544  * L2 cache).
  545  */
  546 static void
  547 init_mendocino(void)
  548 {
  549 #ifdef CPU_PPRO2CELERON
  550         register_t      saveintr;
  551         u_int64_t       bbl_cr_ctl3;
  552 
  553         saveintr = intr_disable();
  554 
  555         load_cr0(rcr0() | CR0_CD | CR0_NW);
  556         wbinvd();
  557 
  558         bbl_cr_ctl3 = rdmsr(MSR_BBL_CR_CTL3);
  559 
  560         /* If the L2 cache is configured, do nothing. */
  561         if (!(bbl_cr_ctl3 & 1)) {
  562                 bbl_cr_ctl3 = 0x134052bLL;
  563 
  564                 /* Set L2 Cache Latency (Default: 5). */
  565 #ifdef  CPU_CELERON_L2_LATENCY
  566 #if CPU_L2_LATENCY > 15
  567 #error invalid CPU_L2_LATENCY.
  568 #endif
  569                 bbl_cr_ctl3 |= CPU_L2_LATENCY << 1;
  570 #else
  571                 bbl_cr_ctl3 |= 5 << 1;
  572 #endif
  573                 wrmsr(MSR_BBL_CR_CTL3, bbl_cr_ctl3);
  574         }
  575 
  576         load_cr0(rcr0() & ~(CR0_CD | CR0_NW));
  577         intr_restore(saveintr);
  578 #endif /* CPU_PPRO2CELERON */
  579 }
  580 
  581 /*
  582  * Initialize special VIA features
  583  */
  584 static void
  585 init_via(void)
  586 {
  587         u_int regs[4], val;
  588         uint64_t fcr;
  589 
  590         /*
  591          * Explicitly enable CX8 and PGE on C3.
  592          *
  593          * http://www.via.com.tw/download/mainboards/6/13/VIA_C3_EBGA%20datasheet110.pdf
  594          */
  595         if (CPUID_TO_MODEL(cpu_id) <= 9)
  596                 fcr = (1 << 1) | (1 << 7);
  597         else
  598                 fcr = 0;
  599 
  600         /*
  601          * Check extended CPUID for PadLock features.
  602          *
  603          * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/programming_guide.pdf
  604          */
  605         do_cpuid(0xc0000000, regs);
  606         if (regs[0] >= 0xc0000001) {
  607                 do_cpuid(0xc0000001, regs);
  608                 val = regs[3];
  609         } else
  610                 val = 0;
  611 
  612         /* Enable RNG if present. */
  613         if ((val & VIA_CPUID_HAS_RNG) != 0) {
  614                 via_feature_rng = VIA_HAS_RNG;
  615                 wrmsr(0x110B, rdmsr(0x110B) | VIA_CPUID_DO_RNG);
  616         }
  617 
  618         /* Enable PadLock if present. */
  619         if ((val & VIA_CPUID_HAS_ACE) != 0)
  620                 via_feature_xcrypt |= VIA_HAS_AES;
  621         if ((val & VIA_CPUID_HAS_ACE2) != 0)
  622                 via_feature_xcrypt |= VIA_HAS_AESCTR;
  623         if ((val & VIA_CPUID_HAS_PHE) != 0)
  624                 via_feature_xcrypt |= VIA_HAS_SHA;
  625         if ((val & VIA_CPUID_HAS_PMM) != 0)
  626                 via_feature_xcrypt |= VIA_HAS_MM;
  627         if (via_feature_xcrypt != 0)
  628                 fcr |= 1 << 28;
  629 
  630         wrmsr(0x1107, rdmsr(0x1107) | fcr);
  631 }
  632 
  633 #endif /* I686_CPU */
  634 
  635 #if defined(I586_CPU) || defined(I686_CPU)
  636 static void
  637 init_transmeta(void)
  638 {
  639         u_int regs[0];
  640 
  641         /* Expose all hidden features. */
  642         wrmsr(0x80860004, rdmsr(0x80860004) | ~0UL);
  643         do_cpuid(1, regs);
  644         cpu_feature = regs[3];
  645 }
  646 #endif
  647 
  648 extern int elf32_nxstack;
  649 
  650 void
  651 initializecpu(void)
  652 {
  653 
  654         switch (cpu) {
  655 #ifdef I486_CPU
  656         case CPU_BLUE:
  657                 init_bluelightning();
  658                 break;
  659         case CPU_486DLC:
  660                 init_486dlc();
  661                 break;
  662         case CPU_CY486DX:
  663                 init_cy486dx();
  664                 break;
  665         case CPU_M1SC:
  666                 init_5x86();
  667                 break;
  668 #ifdef CPU_I486_ON_386
  669         case CPU_486:
  670                 init_i486_on_386();
  671                 break;
  672 #endif
  673         case CPU_M1:
  674                 init_6x86();
  675                 break;
  676 #endif /* I486_CPU */
  677 #ifdef I586_CPU
  678         case CPU_586:
  679                 switch (cpu_vendor_id) {
  680                 case CPU_VENDOR_AMD:
  681 #ifdef CPU_WT_ALLOC
  682                         if (((cpu_id & 0x0f0) > 0) &&
  683                             ((cpu_id & 0x0f0) < 0x60) &&
  684                             ((cpu_id & 0x00f) > 3))
  685                                 enable_K5_wt_alloc();
  686                         else if (((cpu_id & 0x0f0) > 0x80) ||
  687                             (((cpu_id & 0x0f0) == 0x80) &&
  688                                 (cpu_id & 0x00f) > 0x07))
  689                                 enable_K6_2_wt_alloc();
  690                         else if ((cpu_id & 0x0f0) > 0x50)
  691                                 enable_K6_wt_alloc();
  692 #endif
  693                         if ((cpu_id & 0xf0) == 0xa0)
  694                                 /*
  695                                  * Make sure the TSC runs through
  696                                  * suspension, otherwise we can't use
  697                                  * it as timecounter
  698                                  */
  699                                 wrmsr(0x1900, rdmsr(0x1900) | 0x20ULL);
  700                         break;
  701                 case CPU_VENDOR_CENTAUR:
  702                         init_winchip();
  703                         break;
  704                 case CPU_VENDOR_TRANSMETA:
  705                         init_transmeta();
  706                         break;
  707                 case CPU_VENDOR_RISE:
  708                         init_rise();
  709                         break;
  710                 }
  711                 break;
  712 #endif
  713 #ifdef I686_CPU
  714         case CPU_M2:
  715                 init_6x86MX();
  716                 break;
  717         case CPU_686:
  718                 switch (cpu_vendor_id) {
  719                 case CPU_VENDOR_INTEL:
  720                         switch (cpu_id & 0xff0) {
  721                         case 0x610:
  722                                 init_ppro();
  723                                 break;
  724                         case 0x660:
  725                                 init_mendocino();
  726                                 break;
  727                         }
  728                         break;
  729 #ifdef CPU_ATHLON_SSE_HACK
  730                 case CPU_VENDOR_AMD:
  731                         /*
  732                          * Sometimes the BIOS doesn't enable SSE instructions.
  733                          * According to AMD document 20734, the mobile
  734                          * Duron, the (mobile) Athlon 4 and the Athlon MP
  735                          * support SSE. These correspond to cpu_id 0x66X
  736                          * or 0x67X.
  737                          */
  738                         if ((cpu_feature & CPUID_XMM) == 0 &&
  739                             ((cpu_id & ~0xf) == 0x660 ||
  740                              (cpu_id & ~0xf) == 0x670 ||
  741                              (cpu_id & ~0xf) == 0x680)) {
  742                                 u_int regs[4];
  743                                 wrmsr(MSR_HWCR, rdmsr(MSR_HWCR) & ~0x08000);
  744                                 do_cpuid(1, regs);
  745                                 cpu_feature = regs[3];
  746                         }
  747                         break;
  748 #endif
  749                 case CPU_VENDOR_CENTAUR:
  750                         init_via();
  751                         break;
  752                 case CPU_VENDOR_TRANSMETA:
  753                         init_transmeta();
  754                         break;
  755                 }
  756 #if defined(PAE) || defined(PAE_TABLES)
  757                 if ((amd_feature & AMDID_NX) != 0) {
  758                         uint64_t msr;
  759 
  760                         msr = rdmsr(MSR_EFER) | EFER_NXE;
  761                         wrmsr(MSR_EFER, msr);
  762                         pg_nx = PG_NX;
  763                         elf32_nxstack = 1;
  764                 }
  765 #endif
  766                 break;
  767 #endif
  768         default:
  769                 break;
  770         }
  771 #if defined(CPU_ENABLE_SSE)
  772         if ((cpu_feature & CPUID_XMM) && (cpu_feature & CPUID_FXSR)) {
  773                 load_cr4(rcr4() | CR4_FXSR | CR4_XMM);
  774                 cpu_fxsr = hw_instruction_sse = 1;
  775         }
  776 #endif
  777 }
  778 
  779 void
  780 initializecpucache(void)
  781 {
  782 
  783         /*
  784          * CPUID with %eax = 1, %ebx returns
  785          * Bits 15-8: CLFLUSH line size
  786          *      (Value * 8 = cache line size in bytes)
  787          */
  788         if ((cpu_feature & CPUID_CLFSH) != 0)
  789                 cpu_clflush_line_size = ((cpu_procinfo >> 8) & 0xff) * 8;
  790         /*
  791          * XXXKIB: (temporary) hack to work around traps generated
  792          * when CLFLUSHing APIC register window under virtualization
  793          * environments.  These environments tend to disable the
  794          * CPUID_SS feature even though the native CPU supports it.
  795          */
  796         TUNABLE_INT_FETCH("hw.clflush_disable", &hw_clflush_disable);
  797         if (vm_guest != VM_GUEST_NO && hw_clflush_disable == -1) {
  798                 cpu_feature &= ~CPUID_CLFSH;
  799                 cpu_stdext_feature &= ~CPUID_STDEXT_CLFLUSHOPT;
  800         }
  801         /*
  802          * The kernel's use of CLFLUSH{,OPT} can be disabled manually
  803          * by setting the hw.clflush_disable tunable.
  804          */
  805         if (hw_clflush_disable == 1) {
  806                 cpu_feature &= ~CPUID_CLFSH;
  807                 cpu_stdext_feature &= ~CPUID_STDEXT_CLFLUSHOPT;
  808         }
  809 
  810 #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
  811         /*
  812          * OS should flush L1 cache by itself because no PC-98 supports
  813          * non-Intel CPUs.  Use wbinvd instruction before DMA transfer
  814          * when need_pre_dma_flush = 1, use invd instruction after DMA
  815          * transfer when need_post_dma_flush = 1.  If your CPU upgrade
  816          * product supports hardware cache control, you can add the
  817          * CPU_UPGRADE_HW_CACHE option in your kernel configuration file.
  818          * This option eliminates unneeded cache flush instruction(s).
  819          */
  820         if (cpu_vendor_id == CPU_VENDOR_CYRIX) {
  821                 switch (cpu) {
  822 #ifdef I486_CPU
  823                 case CPU_486DLC:
  824                         need_post_dma_flush = 1;
  825                         break;
  826                 case CPU_M1SC:
  827                         need_pre_dma_flush = 1;
  828                         break;
  829                 case CPU_CY486DX:
  830                         need_pre_dma_flush = 1;
  831 #ifdef CPU_I486_ON_386
  832                         need_post_dma_flush = 1;
  833 #endif
  834                         break;
  835 #endif
  836                 default:
  837                         break;
  838                 }
  839         } else if (cpu_vendor_id == CPU_VENDOR_AMD) {
  840                 switch (cpu_id & 0xFF0) {
  841                 case 0x470:             /* Enhanced Am486DX2 WB */
  842                 case 0x490:             /* Enhanced Am486DX4 WB */
  843                 case 0x4F0:             /* Am5x86 WB */
  844                         need_pre_dma_flush = 1;
  845                         break;
  846                 }
  847         } else if (cpu_vendor_id == CPU_VENDOR_IBM) {
  848                 need_post_dma_flush = 1;
  849         } else {
  850 #ifdef CPU_I486_ON_386
  851                 need_pre_dma_flush = 1;
  852 #endif
  853         }
  854 #endif /* PC98 && !CPU_UPGRADE_HW_CACHE */
  855 }
  856 
  857 #if defined(I586_CPU) && defined(CPU_WT_ALLOC)
  858 /*
  859  * Enable write allocate feature of AMD processors.
  860  * Following two functions require the Maxmem variable being set.
  861  */
  862 static void
  863 enable_K5_wt_alloc(void)
  864 {
  865         u_int64_t       msr;
  866         register_t      saveintr;
  867 
  868         /*
  869          * Write allocate is supported only on models 1, 2, and 3, with
  870          * a stepping of 4 or greater.
  871          */
  872         if (((cpu_id & 0xf0) > 0) && ((cpu_id & 0x0f) > 3)) {
  873                 saveintr = intr_disable();
  874                 msr = rdmsr(0x83);              /* HWCR */
  875                 wrmsr(0x83, msr & !(0x10));
  876 
  877                 /*
  878                  * We have to tell the chip where the top of memory is,
  879                  * since video cards could have frame bufferes there,
  880                  * memory-mapped I/O could be there, etc.
  881                  */
  882                 if(Maxmem > 0)
  883                   msr = Maxmem / 16;
  884                 else
  885                   msr = 0;
  886                 msr |= AMD_WT_ALLOC_TME | AMD_WT_ALLOC_FRE;
  887 #ifdef PC98
  888                 if (!(inb(0x43b) & 4)) {
  889                         wrmsr(0x86, 0x0ff00f0);
  890                         msr |= AMD_WT_ALLOC_PRE;
  891                 }
  892 #else
  893                 /*
  894                  * There is no way to know wheter 15-16M hole exists or not. 
  895                  * Therefore, we disable write allocate for this range.
  896                  */
  897                         wrmsr(0x86, 0x0ff00f0);
  898                         msr |= AMD_WT_ALLOC_PRE;
  899 #endif
  900                 wrmsr(0x85, msr);
  901 
  902                 msr=rdmsr(0x83);
  903                 wrmsr(0x83, msr|0x10); /* enable write allocate */
  904                 intr_restore(saveintr);
  905         }
  906 }
  907 
  908 static void
  909 enable_K6_wt_alloc(void)
  910 {
  911         quad_t  size;
  912         u_int64_t       whcr;
  913         register_t      saveintr;
  914 
  915         saveintr = intr_disable();
  916         wbinvd();
  917 
  918 #ifdef CPU_DISABLE_CACHE
  919         /*
  920          * Certain K6-2 box becomes unstable when write allocation is
  921          * enabled.
  922          */
  923         /*
  924          * The AMD-K6 processer provides the 64-bit Test Register 12(TR12),
  925          * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported.
  926          * All other bits in TR12 have no effect on the processer's operation.
  927          * The I/O Trap Restart function (bit 9 of TR12) is always enabled
  928          * on the AMD-K6.
  929          */
  930         wrmsr(0x0000000e, (u_int64_t)0x0008);
  931 #endif
  932         /* Don't assume that memory size is aligned with 4M. */
  933         if (Maxmem > 0)
  934           size = ((Maxmem >> 8) + 3) >> 2;
  935         else
  936           size = 0;
  937 
  938         /* Limit is 508M bytes. */
  939         if (size > 0x7f)
  940                 size = 0x7f;
  941         whcr = (rdmsr(0xc0000082) & ~(0x7fLL << 1)) | (size << 1);
  942 
  943 #if defined(PC98) || defined(NO_MEMORY_HOLE)
  944         if (whcr & (0x7fLL << 1)) {
  945 #ifdef PC98
  946                 /*
  947                  * If bit 2 of port 0x43b is 0, disable wrte allocate for the
  948                  * 15-16M range.
  949                  */
  950                 if (!(inb(0x43b) & 4))
  951                         whcr &= ~0x0001LL;
  952                 else
  953 #endif
  954                         whcr |=  0x0001LL;
  955         }
  956 #else
  957         /*
  958          * There is no way to know wheter 15-16M hole exists or not. 
  959          * Therefore, we disable write allocate for this range.
  960          */
  961         whcr &= ~0x0001LL;
  962 #endif
  963         wrmsr(0x0c0000082, whcr);
  964 
  965         intr_restore(saveintr);
  966 }
  967 
  968 static void
  969 enable_K6_2_wt_alloc(void)
  970 {
  971         quad_t  size;
  972         u_int64_t       whcr;
  973         register_t      saveintr;
  974 
  975         saveintr = intr_disable();
  976         wbinvd();
  977 
  978 #ifdef CPU_DISABLE_CACHE
  979         /*
  980          * Certain K6-2 box becomes unstable when write allocation is
  981          * enabled.
  982          */
  983         /*
  984          * The AMD-K6 processer provides the 64-bit Test Register 12(TR12),
  985          * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported.
  986          * All other bits in TR12 have no effect on the processer's operation.
  987          * The I/O Trap Restart function (bit 9 of TR12) is always enabled
  988          * on the AMD-K6.
  989          */
  990         wrmsr(0x0000000e, (u_int64_t)0x0008);
  991 #endif
  992         /* Don't assume that memory size is aligned with 4M. */
  993         if (Maxmem > 0)
  994           size = ((Maxmem >> 8) + 3) >> 2;
  995         else
  996           size = 0;
  997 
  998         /* Limit is 4092M bytes. */
  999         if (size > 0x3fff)
 1000                 size = 0x3ff;
 1001         whcr = (rdmsr(0xc0000082) & ~(0x3ffLL << 22)) | (size << 22);
 1002 
 1003 #if defined(PC98) || defined(NO_MEMORY_HOLE)
 1004         if (whcr & (0x3ffLL << 22)) {
 1005 #ifdef PC98
 1006                 /*
 1007                  * If bit 2 of port 0x43b is 0, disable wrte allocate for the
 1008                  * 15-16M range.
 1009                  */
 1010                 if (!(inb(0x43b) & 4))
 1011                         whcr &= ~(1LL << 16);
 1012                 else
 1013 #endif
 1014                         whcr |=  1LL << 16;
 1015         }
 1016 #else
 1017         /*
 1018          * There is no way to know wheter 15-16M hole exists or not. 
 1019          * Therefore, we disable write allocate for this range.
 1020          */
 1021         whcr &= ~(1LL << 16);
 1022 #endif
 1023         wrmsr(0x0c0000082, whcr);
 1024 
 1025         intr_restore(saveintr);
 1026 }
 1027 #endif /* I585_CPU && CPU_WT_ALLOC */
 1028 
 1029 #include "opt_ddb.h"
 1030 #ifdef DDB
 1031 #include <ddb/ddb.h>
 1032 
 1033 DB_SHOW_COMMAND(cyrixreg, cyrixreg)
 1034 {
 1035         register_t saveintr;
 1036         u_int   cr0;
 1037         u_char  ccr1, ccr2, ccr3;
 1038         u_char  ccr0 = 0, ccr4 = 0, ccr5 = 0, pcr0 = 0;
 1039 
 1040         cr0 = rcr0();
 1041         if (cpu_vendor_id == CPU_VENDOR_CYRIX) {
 1042                 saveintr = intr_disable();
 1043 
 1044 
 1045                 if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) {
 1046                         ccr0 = read_cyrix_reg(CCR0);
 1047                 }
 1048                 ccr1 = read_cyrix_reg(CCR1);
 1049                 ccr2 = read_cyrix_reg(CCR2);
 1050                 ccr3 = read_cyrix_reg(CCR3);
 1051                 if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) {
 1052                         write_cyrix_reg(CCR3, CCR3_MAPEN0);
 1053                         ccr4 = read_cyrix_reg(CCR4);
 1054                         if ((cpu == CPU_M1) || (cpu == CPU_M2))
 1055                                 ccr5 = read_cyrix_reg(CCR5);
 1056                         else
 1057                                 pcr0 = read_cyrix_reg(PCR0);
 1058                         write_cyrix_reg(CCR3, ccr3);            /* Restore CCR3. */
 1059                 }
 1060                 intr_restore(saveintr);
 1061 
 1062                 if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX))
 1063                         printf("CCR0=%x, ", (u_int)ccr0);
 1064 
 1065                 printf("CCR1=%x, CCR2=%x, CCR3=%x",
 1066                         (u_int)ccr1, (u_int)ccr2, (u_int)ccr3);
 1067                 if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) {
 1068                         printf(", CCR4=%x, ", (u_int)ccr4);
 1069                         if (cpu == CPU_M1SC)
 1070                                 printf("PCR0=%x\n", pcr0);
 1071                         else
 1072                                 printf("CCR5=%x\n", ccr5);
 1073                 }
 1074         }
 1075         printf("CR0=%x\n", cr0);
 1076 }
 1077 #endif /* DDB */

Cache object: 4c0e5366c16a742b192d8918e923f60b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.