1a8e282d6SKATO Takenori /* 24536af6aSKATO Takenori * Copyright (c) KATO Takenori, 1997, 1998. 3a8e282d6SKATO Takenori * 4a8e282d6SKATO Takenori * All rights reserved. Unpublished rights reserved under the copyright 5a8e282d6SKATO Takenori * laws of Japan. 6a8e282d6SKATO Takenori * 7a8e282d6SKATO Takenori * Redistribution and use in source and binary forms, with or without 8a8e282d6SKATO Takenori * modification, are permitted provided that the following conditions 9a8e282d6SKATO Takenori * are met: 10a8e282d6SKATO Takenori * 11a8e282d6SKATO Takenori * 1. Redistributions of source code must retain the above copyright 12a8e282d6SKATO Takenori * notice, this list of conditions and the following disclaimer as 13a8e282d6SKATO Takenori * the first lines of this file unmodified. 14a8e282d6SKATO Takenori * 2. Redistributions in binary form must reproduce the above copyright 15a8e282d6SKATO Takenori * notice, this list of conditions and the following disclaimer in the 16a8e282d6SKATO Takenori * documentation and/or other materials provided with the distribution. 17a8e282d6SKATO Takenori * 18a8e282d6SKATO Takenori * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19a8e282d6SKATO Takenori * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20a8e282d6SKATO Takenori * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21a8e282d6SKATO Takenori * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22a8e282d6SKATO Takenori * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23a8e282d6SKATO Takenori * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24a8e282d6SKATO Takenori * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25a8e282d6SKATO Takenori * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26a8e282d6SKATO Takenori * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27a8e282d6SKATO Takenori * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28a8e282d6SKATO Takenori * 29c3aac50fSPeter Wemm * $FreeBSD$ 30a8e282d6SKATO Takenori */ 31a8e282d6SKATO Takenori 32a8e282d6SKATO Takenori #include "opt_cpu.h" 33a8e282d6SKATO Takenori 34a8e282d6SKATO Takenori #include <sys/param.h> 35a8e282d6SKATO Takenori #include <sys/kernel.h> 36a8e282d6SKATO Takenori #include <sys/systm.h> 379d146ac5SPeter Wemm #include <sys/sysctl.h> 38a8e282d6SKATO Takenori 39a8e282d6SKATO Takenori #include <machine/cputypes.h> 40a8e282d6SKATO Takenori #include <machine/md_var.h> 41a8e282d6SKATO Takenori #include <machine/specialreg.h> 42a8e282d6SKATO Takenori 43f7749f92SPeter Wemm #if !defined(CPU_ENABLE_SSE) && defined(I686_CPU) 44f7749f92SPeter Wemm #define CPU_ENABLE_SSE 45f7749f92SPeter Wemm #endif 46f7749f92SPeter Wemm #if defined(CPU_DISABLE_SSE) 47f7749f92SPeter Wemm #undef CPU_ENABLE_SSE 48f7749f92SPeter Wemm #endif 49f7749f92SPeter Wemm 50a8e282d6SKATO Takenori void initializecpu(void); 514536af6aSKATO Takenori #if defined(I586_CPU) && defined(CPU_WT_ALLOC) 524536af6aSKATO Takenori void enable_K5_wt_alloc(void); 534536af6aSKATO Takenori void enable_K6_wt_alloc(void); 54925f3681SMike Smith void enable_K6_2_wt_alloc(void); 554536af6aSKATO Takenori #endif 564536af6aSKATO Takenori 57a8e282d6SKATO Takenori #ifdef I486_CPU 58a8e282d6SKATO Takenori static void init_5x86(void); 59a8e282d6SKATO Takenori static void init_bluelightning(void); 60a8e282d6SKATO Takenori static void init_486dlc(void); 619ca82267SKATO Takenori static void init_cy486dx(void); 62a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386 63a8e282d6SKATO Takenori static void init_i486_on_386(void); 64a8e282d6SKATO Takenori #endif 65a8e282d6SKATO Takenori static void init_6x86(void); 66a8e282d6SKATO Takenori #endif /* I486_CPU */ 67a8e282d6SKATO Takenori 684877e978SKATO Takenori #ifdef I686_CPU 6920916c1fSKATO Takenori static void init_6x86MX(void); 700d303cbaSKATO Takenori static void init_ppro(void); 7165cbb03cSKATO Takenori static void init_mendocino(void); 7220916c1fSKATO Takenori #endif 734faa812aSPeter Wemm void enable_sse(void); 7420916c1fSKATO Takenori 759d146ac5SPeter Wemm int hw_instruction_sse = 0; 769d146ac5SPeter Wemm SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD, 779d146ac5SPeter Wemm &hw_instruction_sse, 0, 789d146ac5SPeter Wemm "SIMD/MMX2 instructions available in CPU"); 799d146ac5SPeter Wemm 8025ea330aSPeter Wemm /* Must *NOT* be BSS or locore will bzero these after setting them */ 8125ea330aSPeter Wemm int cpu = 0; /* Are we 386, 386sx, 486, etc? */ 8225ea330aSPeter Wemm u_int cpu_id = 0; /* Stepping ID */ 8325ea330aSPeter Wemm u_int cpu_feature = 0; /* Feature flags */ 8425ea330aSPeter Wemm u_int cpu_high = 0; /* Highest arg to CPUID */ 855897d411SPeter Wemm #ifdef CPU_ENABLE_SSE 8625ea330aSPeter Wemm u_int cpu_fxsr = 0; /* SSE enabled */ 875897d411SPeter Wemm #endif 8825ea330aSPeter Wemm char cpu_vendor[20] = ""; /* CPU Origin code */ 895897d411SPeter Wemm 90a8e282d6SKATO Takenori #ifdef I486_CPU 91a8e282d6SKATO Takenori /* 92a8e282d6SKATO Takenori * IBM Blue Lightning 93a8e282d6SKATO Takenori */ 94a8e282d6SKATO Takenori static void 95a8e282d6SKATO Takenori init_bluelightning(void) 96a8e282d6SKATO Takenori { 97a8e282d6SKATO Takenori u_long eflags; 98a8e282d6SKATO Takenori 99a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) 100a8e282d6SKATO Takenori need_post_dma_flush = 1; 101a8e282d6SKATO Takenori #endif 102a8e282d6SKATO Takenori 103a8e282d6SKATO Takenori eflags = read_eflags(); 104a8e282d6SKATO Takenori disable_intr(); 105a8e282d6SKATO Takenori 106a8e282d6SKATO Takenori load_cr0(rcr0() | CR0_CD | CR0_NW); 107a8e282d6SKATO Takenori invd(); 108a8e282d6SKATO Takenori 109a8e282d6SKATO Takenori #ifdef CPU_BLUELIGHTNING_FPU_OP_CACHE 110a8e282d6SKATO Takenori wrmsr(0x1000, 0x9c92LL); /* FP operand can be cacheable on Cyrix FPU */ 111a8e282d6SKATO Takenori #else 112a8e282d6SKATO Takenori wrmsr(0x1000, 0x1c92LL); /* Intel FPU */ 113a8e282d6SKATO Takenori #endif 114a8e282d6SKATO Takenori /* Enables 13MB and 0-640KB cache. */ 115a8e282d6SKATO Takenori wrmsr(0x1001, (0xd0LL << 32) | 0x3ff); 116a8e282d6SKATO Takenori #ifdef CPU_BLUELIGHTNING_3X 117a8e282d6SKATO Takenori wrmsr(0x1002, 0x04000000LL); /* Enables triple-clock mode. */ 118a8e282d6SKATO Takenori #else 119a8e282d6SKATO Takenori wrmsr(0x1002, 0x03000000LL); /* Enables double-clock mode. */ 120a8e282d6SKATO Takenori #endif 121a8e282d6SKATO Takenori 122a8e282d6SKATO Takenori /* Enable caching in CR0. */ 123a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 124a8e282d6SKATO Takenori invd(); 125a8e282d6SKATO Takenori write_eflags(eflags); 126a8e282d6SKATO Takenori } 127a8e282d6SKATO Takenori 128a8e282d6SKATO Takenori /* 1299ca82267SKATO Takenori * Cyrix 486SLC/DLC/SR/DR series 130a8e282d6SKATO Takenori */ 131a8e282d6SKATO Takenori static void 132a8e282d6SKATO Takenori init_486dlc(void) 133a8e282d6SKATO Takenori { 134a8e282d6SKATO Takenori u_long eflags; 135a8e282d6SKATO Takenori u_char ccr0; 136a8e282d6SKATO Takenori 137a8e282d6SKATO Takenori eflags = read_eflags(); 138a8e282d6SKATO Takenori disable_intr(); 139a8e282d6SKATO Takenori invd(); 140a8e282d6SKATO Takenori 141a8e282d6SKATO Takenori ccr0 = read_cyrix_reg(CCR0); 142a8e282d6SKATO Takenori #ifndef CYRIX_CACHE_WORKS 143a8e282d6SKATO Takenori ccr0 |= CCR0_NC1 | CCR0_BARB; 144a8e282d6SKATO Takenori write_cyrix_reg(CCR0, ccr0); 145a8e282d6SKATO Takenori invd(); 146a8e282d6SKATO Takenori #else 147a8e282d6SKATO Takenori ccr0 &= ~CCR0_NC0; 148a8e282d6SKATO Takenori #ifndef CYRIX_CACHE_REALLY_WORKS 149a8e282d6SKATO Takenori ccr0 |= CCR0_NC1 | CCR0_BARB; 150a8e282d6SKATO Takenori #else 151a8e282d6SKATO Takenori ccr0 |= CCR0_NC1; 152a8e282d6SKATO Takenori #endif 1534962d938SKATO Takenori #ifdef CPU_DIRECT_MAPPED_CACHE 1544962d938SKATO Takenori ccr0 |= CCR0_CO; /* Direct mapped mode. */ 1554962d938SKATO Takenori #endif 156a8e282d6SKATO Takenori write_cyrix_reg(CCR0, ccr0); 157a8e282d6SKATO Takenori 158a8e282d6SKATO Takenori /* Clear non-cacheable region. */ 159a8e282d6SKATO Takenori write_cyrix_reg(NCR1+2, NCR_SIZE_0K); 160a8e282d6SKATO Takenori write_cyrix_reg(NCR2+2, NCR_SIZE_0K); 161a8e282d6SKATO Takenori write_cyrix_reg(NCR3+2, NCR_SIZE_0K); 162a8e282d6SKATO Takenori write_cyrix_reg(NCR4+2, NCR_SIZE_0K); 163a8e282d6SKATO Takenori 164a8e282d6SKATO Takenori write_cyrix_reg(0, 0); /* dummy write */ 165a8e282d6SKATO Takenori 166a8e282d6SKATO Takenori /* Enable caching in CR0. */ 167a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 168a8e282d6SKATO Takenori invd(); 169a8e282d6SKATO Takenori #endif /* !CYRIX_CACHE_WORKS */ 170a8e282d6SKATO Takenori write_eflags(eflags); 171a8e282d6SKATO Takenori } 172a8e282d6SKATO Takenori 173a8e282d6SKATO Takenori 174a8e282d6SKATO Takenori /* 1759ca82267SKATO Takenori * Cyrix 486S/DX series 1769ca82267SKATO Takenori */ 1779ca82267SKATO Takenori static void 1789ca82267SKATO Takenori init_cy486dx(void) 1799ca82267SKATO Takenori { 1809ca82267SKATO Takenori u_long eflags; 1819ca82267SKATO Takenori u_char ccr2; 1829ca82267SKATO Takenori 1839ca82267SKATO Takenori eflags = read_eflags(); 1849ca82267SKATO Takenori disable_intr(); 1859ca82267SKATO Takenori invd(); 1869ca82267SKATO Takenori 1879ca82267SKATO Takenori ccr2 = read_cyrix_reg(CCR2); 1881ba2a543SKATO Takenori #ifdef CPU_SUSP_HLT 1891ba2a543SKATO Takenori ccr2 |= CCR2_SUSP_HLT; 1909ca82267SKATO Takenori #endif 1911cfd836fSKATO Takenori 1921cfd836fSKATO Takenori #ifdef PC98 1931cfd836fSKATO Takenori /* Enables WB cache interface pin and Lock NW bit in CR0. */ 1941cfd836fSKATO Takenori ccr2 |= CCR2_WB | CCR2_LOCK_NW; 1951cfd836fSKATO Takenori /* Unlock NW bit in CR0. */ 1961cfd836fSKATO Takenori write_cyrix_reg(CCR2, ccr2 & ~CCR2_LOCK_NW); 1971cfd836fSKATO Takenori load_cr0((rcr0() & ~CR0_CD) | CR0_NW); /* CD = 0, NW = 1 */ 1981cfd836fSKATO Takenori #endif 1991cfd836fSKATO Takenori 2009ca82267SKATO Takenori write_cyrix_reg(CCR2, ccr2); 2019ca82267SKATO Takenori write_eflags(eflags); 2029ca82267SKATO Takenori } 2039ca82267SKATO Takenori 2049ca82267SKATO Takenori 2059ca82267SKATO Takenori /* 206a8e282d6SKATO Takenori * Cyrix 5x86 207a8e282d6SKATO Takenori */ 208a8e282d6SKATO Takenori static void 209a8e282d6SKATO Takenori init_5x86(void) 210a8e282d6SKATO Takenori { 211a8e282d6SKATO Takenori u_long eflags; 212a8e282d6SKATO Takenori u_char ccr2, ccr3, ccr4, pcr0; 213a8e282d6SKATO Takenori 214a8e282d6SKATO Takenori eflags = read_eflags(); 215a8e282d6SKATO Takenori disable_intr(); 216a8e282d6SKATO Takenori 217a8e282d6SKATO Takenori load_cr0(rcr0() | CR0_CD | CR0_NW); 218a8e282d6SKATO Takenori wbinvd(); 219a8e282d6SKATO Takenori 220a8e282d6SKATO Takenori (void)read_cyrix_reg(CCR3); /* dummy */ 221a8e282d6SKATO Takenori 222a8e282d6SKATO Takenori /* Initialize CCR2. */ 223a8e282d6SKATO Takenori ccr2 = read_cyrix_reg(CCR2); 224a8e282d6SKATO Takenori ccr2 |= CCR2_WB; 225a8e282d6SKATO Takenori #ifdef CPU_SUSP_HLT 226a8e282d6SKATO Takenori ccr2 |= CCR2_SUSP_HLT; 227a8e282d6SKATO Takenori #else 228a8e282d6SKATO Takenori ccr2 &= ~CCR2_SUSP_HLT; 229a8e282d6SKATO Takenori #endif 230a8e282d6SKATO Takenori ccr2 |= CCR2_WT1; 231a8e282d6SKATO Takenori write_cyrix_reg(CCR2, ccr2); 232a8e282d6SKATO Takenori 233a8e282d6SKATO Takenori /* Initialize CCR4. */ 234a8e282d6SKATO Takenori ccr3 = read_cyrix_reg(CCR3); 235a8e282d6SKATO Takenori write_cyrix_reg(CCR3, CCR3_MAPEN0); 236a8e282d6SKATO Takenori 237a8e282d6SKATO Takenori ccr4 = read_cyrix_reg(CCR4); 238a8e282d6SKATO Takenori ccr4 |= CCR4_DTE; 239a8e282d6SKATO Takenori ccr4 |= CCR4_MEM; 240a8e282d6SKATO Takenori #ifdef CPU_FASTER_5X86_FPU 241a8e282d6SKATO Takenori ccr4 |= CCR4_FASTFPE; 242a8e282d6SKATO Takenori #else 243a8e282d6SKATO Takenori ccr4 &= ~CCR4_FASTFPE; 244a8e282d6SKATO Takenori #endif 245a8e282d6SKATO Takenori ccr4 &= ~CCR4_IOMASK; 246a8e282d6SKATO Takenori /******************************************************************** 247a8e282d6SKATO Takenori * WARNING: The "BIOS Writers Guide" mentions that I/O recovery time 248a8e282d6SKATO Takenori * should be 0 for errata fix. 249a8e282d6SKATO Takenori ********************************************************************/ 250a8e282d6SKATO Takenori #ifdef CPU_IORT 251a8e282d6SKATO Takenori ccr4 |= CPU_IORT & CCR4_IOMASK; 252a8e282d6SKATO Takenori #endif 253a8e282d6SKATO Takenori write_cyrix_reg(CCR4, ccr4); 254a8e282d6SKATO Takenori 255a8e282d6SKATO Takenori /* Initialize PCR0. */ 256a8e282d6SKATO Takenori /**************************************************************** 257a8e282d6SKATO Takenori * WARNING: RSTK_EN and LOOP_EN could make your system unstable. 258a8e282d6SKATO Takenori * BTB_EN might make your system unstable. 259a8e282d6SKATO Takenori ****************************************************************/ 260a8e282d6SKATO Takenori pcr0 = read_cyrix_reg(PCR0); 261a8e282d6SKATO Takenori #ifdef CPU_RSTK_EN 262a8e282d6SKATO Takenori pcr0 |= PCR0_RSTK; 263a8e282d6SKATO Takenori #else 264a8e282d6SKATO Takenori pcr0 &= ~PCR0_RSTK; 265a8e282d6SKATO Takenori #endif 266a8e282d6SKATO Takenori #ifdef CPU_BTB_EN 267a8e282d6SKATO Takenori pcr0 |= PCR0_BTB; 268a8e282d6SKATO Takenori #else 269a8e282d6SKATO Takenori pcr0 &= ~PCR0_BTB; 270a8e282d6SKATO Takenori #endif 271a8e282d6SKATO Takenori #ifdef CPU_LOOP_EN 272a8e282d6SKATO Takenori pcr0 |= PCR0_LOOP; 273a8e282d6SKATO Takenori #else 274a8e282d6SKATO Takenori pcr0 &= ~PCR0_LOOP; 275a8e282d6SKATO Takenori #endif 276a8e282d6SKATO Takenori 277a8e282d6SKATO Takenori /**************************************************************** 278a8e282d6SKATO Takenori * WARNING: if you use a memory mapped I/O device, don't use 279a8e282d6SKATO Takenori * DISABLE_5X86_LSSER option, which may reorder memory mapped 280a8e282d6SKATO Takenori * I/O access. 281a8e282d6SKATO Takenori * IF YOUR MOTHERBOARD HAS PCI BUS, DON'T DISABLE LSSER. 282a8e282d6SKATO Takenori ****************************************************************/ 283a8e282d6SKATO Takenori #ifdef CPU_DISABLE_5X86_LSSER 284a8e282d6SKATO Takenori pcr0 &= ~PCR0_LSSER; 285a8e282d6SKATO Takenori #else 286a8e282d6SKATO Takenori pcr0 |= PCR0_LSSER; 287a8e282d6SKATO Takenori #endif 288a8e282d6SKATO Takenori write_cyrix_reg(PCR0, pcr0); 289a8e282d6SKATO Takenori 290a8e282d6SKATO Takenori /* Restore CCR3. */ 291a8e282d6SKATO Takenori write_cyrix_reg(CCR3, ccr3); 292a8e282d6SKATO Takenori 293a8e282d6SKATO Takenori (void)read_cyrix_reg(0x80); /* dummy */ 294a8e282d6SKATO Takenori 295a8e282d6SKATO Takenori /* Unlock NW bit in CR0. */ 296a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW); 297a8e282d6SKATO Takenori load_cr0((rcr0() & ~CR0_CD) | CR0_NW); /* CD = 0, NW = 1 */ 298a8e282d6SKATO Takenori /* Lock NW bit in CR0. */ 299a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW); 300a8e282d6SKATO Takenori 301a8e282d6SKATO Takenori write_eflags(eflags); 302a8e282d6SKATO Takenori } 303a8e282d6SKATO Takenori 304a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386 305a8e282d6SKATO Takenori /* 306a8e282d6SKATO Takenori * There are i486 based upgrade products for i386 machines. 307a8e282d6SKATO Takenori * In this case, BIOS doesn't enables CPU cache. 308a8e282d6SKATO Takenori */ 3091eaae5cbSPoul-Henning Kamp static void 310a8e282d6SKATO Takenori init_i486_on_386(void) 311a8e282d6SKATO Takenori { 312a8e282d6SKATO Takenori u_long eflags; 313a8e282d6SKATO Takenori 314a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) 315a8e282d6SKATO Takenori need_post_dma_flush = 1; 316a8e282d6SKATO Takenori #endif 317a8e282d6SKATO Takenori 318a8e282d6SKATO Takenori eflags = read_eflags(); 319a8e282d6SKATO Takenori disable_intr(); 320a8e282d6SKATO Takenori 321a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0, NW = 0 */ 322a8e282d6SKATO Takenori 3235fa4a058SKATO Takenori write_eflags(eflags); 324a8e282d6SKATO Takenori } 325a8e282d6SKATO Takenori #endif 326a8e282d6SKATO Takenori 327a8e282d6SKATO Takenori /* 328a8e282d6SKATO Takenori * Cyrix 6x86 329a8e282d6SKATO Takenori * 330a8e282d6SKATO Takenori * XXX - What should I do here? Please let me know. 331a8e282d6SKATO Takenori */ 332a8e282d6SKATO Takenori static void 333a8e282d6SKATO Takenori init_6x86(void) 334a8e282d6SKATO Takenori { 335a8e282d6SKATO Takenori u_long eflags; 336a8e282d6SKATO Takenori u_char ccr3, ccr4; 337a8e282d6SKATO Takenori 338a8e282d6SKATO Takenori eflags = read_eflags(); 339a8e282d6SKATO Takenori disable_intr(); 340a8e282d6SKATO Takenori 341a8e282d6SKATO Takenori load_cr0(rcr0() | CR0_CD | CR0_NW); 342a8e282d6SKATO Takenori wbinvd(); 343a8e282d6SKATO Takenori 344a8e282d6SKATO Takenori /* Initialize CCR0. */ 345a8e282d6SKATO Takenori write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1); 346a8e282d6SKATO Takenori 3476593be60SKATO Takenori /* Initialize CCR1. */ 3486593be60SKATO Takenori #ifdef CPU_CYRIX_NO_LOCK 349b20f1ceeSJonathan Lemon write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK); 3506593be60SKATO Takenori #else 351b20f1ceeSJonathan Lemon write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK); 3526593be60SKATO Takenori #endif 3536593be60SKATO Takenori 354a8e282d6SKATO Takenori /* Initialize CCR2. */ 355a8e282d6SKATO Takenori #ifdef CPU_SUSP_HLT 356a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT); 357a8e282d6SKATO Takenori #else 358a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT); 359a8e282d6SKATO Takenori #endif 360a8e282d6SKATO Takenori 361a8e282d6SKATO Takenori ccr3 = read_cyrix_reg(CCR3); 362a8e282d6SKATO Takenori write_cyrix_reg(CCR3, CCR3_MAPEN0); 363a8e282d6SKATO Takenori 364a8e282d6SKATO Takenori /* Initialize CCR4. */ 365a8e282d6SKATO Takenori ccr4 = read_cyrix_reg(CCR4); 366a8e282d6SKATO Takenori ccr4 |= CCR4_DTE; 367a8e282d6SKATO Takenori ccr4 &= ~CCR4_IOMASK; 368a8e282d6SKATO Takenori #ifdef CPU_IORT 369a8e282d6SKATO Takenori write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK)); 370a8e282d6SKATO Takenori #else 371a8e282d6SKATO Takenori write_cyrix_reg(CCR4, ccr4 | 7); 372a8e282d6SKATO Takenori #endif 373a8e282d6SKATO Takenori 3746593be60SKATO Takenori /* Initialize CCR5. */ 3756593be60SKATO Takenori #ifdef CPU_WT_ALLOC 3766593be60SKATO Takenori write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC); 3776593be60SKATO Takenori #endif 3786593be60SKATO Takenori 379a8e282d6SKATO Takenori /* Restore CCR3. */ 380a8e282d6SKATO Takenori write_cyrix_reg(CCR3, ccr3); 381a8e282d6SKATO Takenori 382a8e282d6SKATO Takenori /* Unlock NW bit in CR0. */ 383a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW); 384a8e282d6SKATO Takenori 385a8e282d6SKATO Takenori /* 386a8e282d6SKATO Takenori * Earlier revision of the 6x86 CPU could crash the system if 387a8e282d6SKATO Takenori * L1 cache is in write-back mode. 388a8e282d6SKATO Takenori */ 389a8e282d6SKATO Takenori if ((cyrix_did & 0xff00) > 0x1600) 390a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 391a8e282d6SKATO Takenori else { 392a8e282d6SKATO Takenori /* Revision 2.6 and lower. */ 393a8e282d6SKATO Takenori #ifdef CYRIX_CACHE_REALLY_WORKS 394a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 395a8e282d6SKATO Takenori #else 396a8e282d6SKATO Takenori load_cr0((rcr0() & ~CR0_CD) | CR0_NW); /* CD = 0 and NW = 1 */ 397a8e282d6SKATO Takenori #endif 398a8e282d6SKATO Takenori } 399a8e282d6SKATO Takenori 400a8e282d6SKATO Takenori /* Lock NW bit in CR0. */ 401a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW); 402a8e282d6SKATO Takenori 403a8e282d6SKATO Takenori write_eflags(eflags); 404a8e282d6SKATO Takenori } 405a8e282d6SKATO Takenori #endif /* I486_CPU */ 406a8e282d6SKATO Takenori 4074877e978SKATO Takenori #ifdef I686_CPU 40820916c1fSKATO Takenori /* 40920916c1fSKATO Takenori * Cyrix 6x86MX (code-named M2) 41020916c1fSKATO Takenori * 41120916c1fSKATO Takenori * XXX - What should I do here? Please let me know. 41220916c1fSKATO Takenori */ 41320916c1fSKATO Takenori static void 41420916c1fSKATO Takenori init_6x86MX(void) 41520916c1fSKATO Takenori { 41620916c1fSKATO Takenori u_long eflags; 41720916c1fSKATO Takenori u_char ccr3, ccr4; 41820916c1fSKATO Takenori 41920916c1fSKATO Takenori eflags = read_eflags(); 42020916c1fSKATO Takenori disable_intr(); 42120916c1fSKATO Takenori 42220916c1fSKATO Takenori load_cr0(rcr0() | CR0_CD | CR0_NW); 42320916c1fSKATO Takenori wbinvd(); 42420916c1fSKATO Takenori 42520916c1fSKATO Takenori /* Initialize CCR0. */ 42620916c1fSKATO Takenori write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1); 42720916c1fSKATO Takenori 4286593be60SKATO Takenori /* Initialize CCR1. */ 4296593be60SKATO Takenori #ifdef CPU_CYRIX_NO_LOCK 430b20f1ceeSJonathan Lemon write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK); 4316593be60SKATO Takenori #else 432b20f1ceeSJonathan Lemon write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK); 4336593be60SKATO Takenori #endif 4346593be60SKATO Takenori 43520916c1fSKATO Takenori /* Initialize CCR2. */ 43620916c1fSKATO Takenori #ifdef CPU_SUSP_HLT 43720916c1fSKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT); 43820916c1fSKATO Takenori #else 43920916c1fSKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT); 44020916c1fSKATO Takenori #endif 44120916c1fSKATO Takenori 44220916c1fSKATO Takenori ccr3 = read_cyrix_reg(CCR3); 44320916c1fSKATO Takenori write_cyrix_reg(CCR3, CCR3_MAPEN0); 44420916c1fSKATO Takenori 44520916c1fSKATO Takenori /* Initialize CCR4. */ 44620916c1fSKATO Takenori ccr4 = read_cyrix_reg(CCR4); 44720916c1fSKATO Takenori ccr4 &= ~CCR4_IOMASK; 44820916c1fSKATO Takenori #ifdef CPU_IORT 44920916c1fSKATO Takenori write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK)); 45020916c1fSKATO Takenori #else 45120916c1fSKATO Takenori write_cyrix_reg(CCR4, ccr4 | 7); 45220916c1fSKATO Takenori #endif 45320916c1fSKATO Takenori 4546593be60SKATO Takenori /* Initialize CCR5. */ 4556593be60SKATO Takenori #ifdef CPU_WT_ALLOC 4566593be60SKATO Takenori write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC); 4576593be60SKATO Takenori #endif 4586593be60SKATO Takenori 45920916c1fSKATO Takenori /* Restore CCR3. */ 46020916c1fSKATO Takenori write_cyrix_reg(CCR3, ccr3); 46120916c1fSKATO Takenori 46220916c1fSKATO Takenori /* Unlock NW bit in CR0. */ 46320916c1fSKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW); 46420916c1fSKATO Takenori 46520916c1fSKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 46620916c1fSKATO Takenori 46720916c1fSKATO Takenori /* Lock NW bit in CR0. */ 46820916c1fSKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW); 46920916c1fSKATO Takenori 47020916c1fSKATO Takenori write_eflags(eflags); 47120916c1fSKATO Takenori } 4720d303cbaSKATO Takenori 4730d303cbaSKATO Takenori static void 4740d303cbaSKATO Takenori init_ppro(void) 4750d303cbaSKATO Takenori { 4760d303cbaSKATO Takenori #ifndef SMP 4774536af6aSKATO Takenori u_int64_t apicbase; 4780d303cbaSKATO Takenori 4790d303cbaSKATO Takenori /* 4800d303cbaSKATO Takenori * Local APIC should be diabled in UP kernel. 4810d303cbaSKATO Takenori */ 4820d303cbaSKATO Takenori apicbase = rdmsr(0x1b); 4830d303cbaSKATO Takenori apicbase &= ~0x800LL; 4840d303cbaSKATO Takenori wrmsr(0x1b, apicbase); 4850d303cbaSKATO Takenori #endif 4860d303cbaSKATO Takenori } 48765cbb03cSKATO Takenori 48865cbb03cSKATO Takenori /* 48965cbb03cSKATO Takenori * Initialize BBL_CR_CTL3 (Control register 3: used to configure the 49065cbb03cSKATO Takenori * L2 cache). 49165cbb03cSKATO Takenori */ 49237c84183SPoul-Henning Kamp static void 49365cbb03cSKATO Takenori init_mendocino(void) 49465cbb03cSKATO Takenori { 49565cbb03cSKATO Takenori #ifdef CPU_PPRO2CELERON 49665cbb03cSKATO Takenori u_long eflags; 49765cbb03cSKATO Takenori u_int64_t bbl_cr_ctl3; 49865cbb03cSKATO Takenori 49965cbb03cSKATO Takenori eflags = read_eflags(); 50065cbb03cSKATO Takenori disable_intr(); 50165cbb03cSKATO Takenori 50265cbb03cSKATO Takenori load_cr0(rcr0() | CR0_CD | CR0_NW); 50365cbb03cSKATO Takenori wbinvd(); 50465cbb03cSKATO Takenori 50565cbb03cSKATO Takenori bbl_cr_ctl3 = rdmsr(0x11e); 50665cbb03cSKATO Takenori 50765cbb03cSKATO Takenori /* If the L2 cache is configured, do nothing. */ 50865cbb03cSKATO Takenori if (!(bbl_cr_ctl3 & 1)) { 50965cbb03cSKATO Takenori bbl_cr_ctl3 = 0x134052bLL; 51065cbb03cSKATO Takenori 51165cbb03cSKATO Takenori /* Set L2 Cache Latency (Default: 5). */ 51265cbb03cSKATO Takenori #ifdef CPU_CELERON_L2_LATENCY 51365cbb03cSKATO Takenori #if CPU_L2_LATENCY > 15 51465cbb03cSKATO Takenori #error invalid CPU_L2_LATENCY. 51565cbb03cSKATO Takenori #endif 51665cbb03cSKATO Takenori bbl_cr_ctl3 |= CPU_L2_LATENCY << 1; 51765cbb03cSKATO Takenori #else 51865cbb03cSKATO Takenori bbl_cr_ctl3 |= 5 << 1; 51965cbb03cSKATO Takenori #endif 52065cbb03cSKATO Takenori wrmsr(0x11e, bbl_cr_ctl3); 52165cbb03cSKATO Takenori } 52265cbb03cSKATO Takenori 52365cbb03cSKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); 52465cbb03cSKATO Takenori write_eflags(eflags); 52565cbb03cSKATO Takenori #endif /* CPU_PPRO2CELERON */ 52665cbb03cSKATO Takenori } 52765cbb03cSKATO Takenori 5284faa812aSPeter Wemm #endif /* I686_CPU */ 5294faa812aSPeter Wemm 5309d146ac5SPeter Wemm /* 5319d146ac5SPeter Wemm * Initialize CR4 (Control register 4) to enable SSE instructions. 5329d146ac5SPeter Wemm */ 5339d146ac5SPeter Wemm void 5349d146ac5SPeter Wemm enable_sse(void) 5359d146ac5SPeter Wemm { 5369d146ac5SPeter Wemm #if defined(CPU_ENABLE_SSE) 5379d146ac5SPeter Wemm if ((cpu_feature & CPUID_XMM) && (cpu_feature & CPUID_FXSR)) { 5389d146ac5SPeter Wemm load_cr4(rcr4() | CR4_FXSR | CR4_XMM); 5399d146ac5SPeter Wemm cpu_fxsr = hw_instruction_sse = 1; 5409d146ac5SPeter Wemm } 5419d146ac5SPeter Wemm #endif 5429d146ac5SPeter Wemm } 5439d146ac5SPeter Wemm 544a8e282d6SKATO Takenori void 545a8e282d6SKATO Takenori initializecpu(void) 546a8e282d6SKATO Takenori { 547a8e282d6SKATO Takenori 548a8e282d6SKATO Takenori switch (cpu) { 549a8e282d6SKATO Takenori #ifdef I486_CPU 550a8e282d6SKATO Takenori case CPU_BLUE: 551a8e282d6SKATO Takenori init_bluelightning(); 552a8e282d6SKATO Takenori break; 553a8e282d6SKATO Takenori case CPU_486DLC: 554a8e282d6SKATO Takenori init_486dlc(); 555a8e282d6SKATO Takenori break; 5569ca82267SKATO Takenori case CPU_CY486DX: 5579ca82267SKATO Takenori init_cy486dx(); 5589ca82267SKATO Takenori break; 559a8e282d6SKATO Takenori case CPU_M1SC: 560a8e282d6SKATO Takenori init_5x86(); 561a8e282d6SKATO Takenori break; 562a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386 563a8e282d6SKATO Takenori case CPU_486: 564a8e282d6SKATO Takenori init_i486_on_386(); 565a8e282d6SKATO Takenori break; 566a8e282d6SKATO Takenori #endif 567a8e282d6SKATO Takenori case CPU_M1: 568a8e282d6SKATO Takenori init_6x86(); 569a8e282d6SKATO Takenori break; 570a8e282d6SKATO Takenori #endif /* I486_CPU */ 5714877e978SKATO Takenori #ifdef I686_CPU 57220916c1fSKATO Takenori case CPU_M2: 57320916c1fSKATO Takenori init_6x86MX(); 57420916c1fSKATO Takenori break; 5750d303cbaSKATO Takenori case CPU_686: 57665cbb03cSKATO Takenori if (strcmp(cpu_vendor, "GenuineIntel") == 0) { 57765cbb03cSKATO Takenori switch (cpu_id & 0xff0) { 57865cbb03cSKATO Takenori case 0x610: 5790d303cbaSKATO Takenori init_ppro(); 5800d303cbaSKATO Takenori break; 58165cbb03cSKATO Takenori case 0x660: 58265cbb03cSKATO Takenori init_mendocino(); 58365cbb03cSKATO Takenori break; 58465cbb03cSKATO Takenori } 5856df7ca7bSDavid Malone } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { 5866df7ca7bSDavid Malone #if defined(I686_CPU) && defined(CPU_ATHLON_SSE_HACK) 5876df7ca7bSDavid Malone /* 5886df7ca7bSDavid Malone * Sometimes the BIOS doesn't enable SSE instructions. 5896df7ca7bSDavid Malone * According to AMD document 20734, the mobile 5906df7ca7bSDavid Malone * Duron, the (mobile) Athlon 4 and the Athlon MP 5916df7ca7bSDavid Malone * support SSE. These correspond to cpu_id 0x66X 5926df7ca7bSDavid Malone * or 0x67X. 5936df7ca7bSDavid Malone */ 5946df7ca7bSDavid Malone if ((cpu_feature & CPUID_XMM) == 0 && 5956df7ca7bSDavid Malone ((cpu_id & ~0xf) == 0x660 || 5966df7ca7bSDavid Malone (cpu_id & ~0xf) == 0x670)) { 5976df7ca7bSDavid Malone u_int regs[4]; 5986df7ca7bSDavid Malone wrmsr(0xC0010015, rdmsr(0xC0010015) & ~0x08000); 5996df7ca7bSDavid Malone do_cpuid(1, regs); 6006df7ca7bSDavid Malone cpu_feature = regs[3]; 6016df7ca7bSDavid Malone } 6026df7ca7bSDavid Malone #endif 60365cbb03cSKATO Takenori } 60465cbb03cSKATO Takenori break; 60520916c1fSKATO Takenori #endif 606a8e282d6SKATO Takenori default: 607a8e282d6SKATO Takenori break; 608a8e282d6SKATO Takenori } 609aa32e9a9SPeter Wemm enable_sse(); 610a8e282d6SKATO Takenori 611a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) 612a8e282d6SKATO Takenori /* 6135b488b34SJeroen Ruigrok van der Werven * OS should flush L1 cache by itself because no PC-98 supports 614a8e282d6SKATO Takenori * non-Intel CPUs. Use wbinvd instruction before DMA transfer 615a8e282d6SKATO Takenori * when need_pre_dma_flush = 1, use invd instruction after DMA 616a8e282d6SKATO Takenori * transfer when need_post_dma_flush = 1. If your CPU upgrade 6175b488b34SJeroen Ruigrok van der Werven * product supports hardware cache control, you can add the 618a47ea7b9SJeroen Ruigrok van der Werven * CPU_UPGRADE_HW_CACHE option in your kernel configuration file. 6195b488b34SJeroen Ruigrok van der Werven * This option eliminates unneeded cache flush instruction(s). 620a8e282d6SKATO Takenori */ 621a8e282d6SKATO Takenori if (strcmp(cpu_vendor, "CyrixInstead") == 0) { 622a8e282d6SKATO Takenori switch (cpu) { 623a8e282d6SKATO Takenori #ifdef I486_CPU 624a8e282d6SKATO Takenori case CPU_486DLC: 625a8e282d6SKATO Takenori need_post_dma_flush = 1; 626a8e282d6SKATO Takenori break; 627a8e282d6SKATO Takenori case CPU_M1SC: 628a8e282d6SKATO Takenori need_pre_dma_flush = 1; 629a8e282d6SKATO Takenori break; 6301cfd836fSKATO Takenori case CPU_CY486DX: 6311cfd836fSKATO Takenori need_pre_dma_flush = 1; 6321cfd836fSKATO Takenori #ifdef CPU_I486_ON_386 6331cfd836fSKATO Takenori need_post_dma_flush = 1; 6341cfd836fSKATO Takenori #endif 6351cfd836fSKATO Takenori break; 636a8e282d6SKATO Takenori #endif 637a8e282d6SKATO Takenori default: 638a8e282d6SKATO Takenori break; 639a8e282d6SKATO Takenori } 640a8e282d6SKATO Takenori } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { 641a8e282d6SKATO Takenori switch (cpu_id & 0xFF0) { 642a8e282d6SKATO Takenori case 0x470: /* Enhanced Am486DX2 WB */ 643a8e282d6SKATO Takenori case 0x490: /* Enhanced Am486DX4 WB */ 644a8e282d6SKATO Takenori case 0x4F0: /* Am5x86 WB */ 645a8e282d6SKATO Takenori need_pre_dma_flush = 1; 646a8e282d6SKATO Takenori break; 647a8e282d6SKATO Takenori } 648a8e282d6SKATO Takenori } else if (strcmp(cpu_vendor, "IBM") == 0) { 649a8e282d6SKATO Takenori need_post_dma_flush = 1; 650a8e282d6SKATO Takenori } else { 651a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386 652a8e282d6SKATO Takenori need_pre_dma_flush = 1; 653a8e282d6SKATO Takenori #endif 654a8e282d6SKATO Takenori } 655a47ea7b9SJeroen Ruigrok van der Werven #endif /* PC98 && !CPU_UPGRADE_HW_CACHE */ 656a8e282d6SKATO Takenori } 657a8e282d6SKATO Takenori 6584536af6aSKATO Takenori #if defined(I586_CPU) && defined(CPU_WT_ALLOC) 6594536af6aSKATO Takenori /* 6604536af6aSKATO Takenori * Enable write allocate feature of AMD processors. 6614536af6aSKATO Takenori * Following two functions require the Maxmem variable being set. 6624536af6aSKATO Takenori */ 6634536af6aSKATO Takenori void 6644536af6aSKATO Takenori enable_K5_wt_alloc(void) 6654536af6aSKATO Takenori { 6664536af6aSKATO Takenori u_int64_t msr; 667ba74981eSWarner Losh register_t savecrit; 6684536af6aSKATO Takenori 6694536af6aSKATO Takenori /* 6704536af6aSKATO Takenori * Write allocate is supported only on models 1, 2, and 3, with 6714536af6aSKATO Takenori * a stepping of 4 or greater. 6724536af6aSKATO Takenori */ 6734536af6aSKATO Takenori if (((cpu_id & 0xf0) > 0) && ((cpu_id & 0x0f) > 3)) { 674ba74981eSWarner Losh savecrit = intr_disable(); 6754536af6aSKATO Takenori msr = rdmsr(0x83); /* HWCR */ 6764536af6aSKATO Takenori wrmsr(0x83, msr & !(0x10)); 6774536af6aSKATO Takenori 6784536af6aSKATO Takenori /* 6794536af6aSKATO Takenori * We have to tell the chip where the top of memory is, 6804536af6aSKATO Takenori * since video cards could have frame bufferes there, 6814536af6aSKATO Takenori * memory-mapped I/O could be there, etc. 6824536af6aSKATO Takenori */ 6834536af6aSKATO Takenori if(Maxmem > 0) 6844536af6aSKATO Takenori msr = Maxmem / 16; 6854536af6aSKATO Takenori else 6864536af6aSKATO Takenori msr = 0; 6874536af6aSKATO Takenori msr |= AMD_WT_ALLOC_TME | AMD_WT_ALLOC_FRE; 6884536af6aSKATO Takenori #ifdef PC98 6894536af6aSKATO Takenori if (!(inb(0x43b) & 4)) { 6904536af6aSKATO Takenori wrmsr(0x86, 0x0ff00f0); 6914536af6aSKATO Takenori msr |= AMD_WT_ALLOC_PRE; 6924536af6aSKATO Takenori } 6934536af6aSKATO Takenori #else 6944536af6aSKATO Takenori /* 6954536af6aSKATO Takenori * There is no way to know wheter 15-16M hole exists or not. 6964536af6aSKATO Takenori * Therefore, we disable write allocate for this range. 6974536af6aSKATO Takenori */ 6984536af6aSKATO Takenori wrmsr(0x86, 0x0ff00f0); 6994536af6aSKATO Takenori msr |= AMD_WT_ALLOC_PRE; 7004536af6aSKATO Takenori #endif 7014536af6aSKATO Takenori wrmsr(0x85, msr); 7024536af6aSKATO Takenori 7034536af6aSKATO Takenori msr=rdmsr(0x83); 7044536af6aSKATO Takenori wrmsr(0x83, msr|0x10); /* enable write allocate */ 705ba74981eSWarner Losh intr_restore(savecrit); 7064536af6aSKATO Takenori } 7074536af6aSKATO Takenori } 7084536af6aSKATO Takenori 7094536af6aSKATO Takenori void 7104536af6aSKATO Takenori enable_K6_wt_alloc(void) 7114536af6aSKATO Takenori { 7124536af6aSKATO Takenori quad_t size; 7134536af6aSKATO Takenori u_int64_t whcr; 7144536af6aSKATO Takenori u_long eflags; 7154536af6aSKATO Takenori 7164536af6aSKATO Takenori eflags = read_eflags(); 7174536af6aSKATO Takenori disable_intr(); 7184536af6aSKATO Takenori wbinvd(); 7194536af6aSKATO Takenori 7204536af6aSKATO Takenori #ifdef CPU_DISABLE_CACHE 7214536af6aSKATO Takenori /* 7224536af6aSKATO Takenori * Certain K6-2 box becomes unstable when write allocation is 7234536af6aSKATO Takenori * enabled. 7244536af6aSKATO Takenori */ 7254536af6aSKATO Takenori /* 7264536af6aSKATO Takenori * The AMD-K6 processer provides the 64-bit Test Register 12(TR12), 7274536af6aSKATO Takenori * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported. 7284536af6aSKATO Takenori * All other bits in TR12 have no effect on the processer's operation. 7294536af6aSKATO Takenori * The I/O Trap Restart function (bit 9 of TR12) is always enabled 7304536af6aSKATO Takenori * on the AMD-K6. 7314536af6aSKATO Takenori */ 7324536af6aSKATO Takenori wrmsr(0x0000000e, (u_int64_t)0x0008); 7334536af6aSKATO Takenori #endif 7344536af6aSKATO Takenori /* Don't assume that memory size is aligned with 4M. */ 7354536af6aSKATO Takenori if (Maxmem > 0) 7364b055742SKATO Takenori size = ((Maxmem >> 8) + 3) >> 2; 7374536af6aSKATO Takenori else 7384536af6aSKATO Takenori size = 0; 7394536af6aSKATO Takenori 7404536af6aSKATO Takenori /* Limit is 508M bytes. */ 7414b055742SKATO Takenori if (size > 0x7f) 7424b055742SKATO Takenori size = 0x7f; 7434b055742SKATO Takenori whcr = (rdmsr(0xc0000082) & ~(0x7fLL << 1)) | (size << 1); 7444536af6aSKATO Takenori 745925f3681SMike Smith #if defined(PC98) || defined(NO_MEMORY_HOLE) 7464b055742SKATO Takenori if (whcr & (0x7fLL << 1)) { 747925f3681SMike Smith #ifdef PC98 7484536af6aSKATO Takenori /* 7494536af6aSKATO Takenori * If bit 2 of port 0x43b is 0, disable wrte allocate for the 7504536af6aSKATO Takenori * 15-16M range. 7514536af6aSKATO Takenori */ 7524536af6aSKATO Takenori if (!(inb(0x43b) & 4)) 7534536af6aSKATO Takenori whcr &= ~0x0001LL; 7544536af6aSKATO Takenori else 755925f3681SMike Smith #endif 7564536af6aSKATO Takenori whcr |= 0x0001LL; 7574536af6aSKATO Takenori } 7584536af6aSKATO Takenori #else 7594536af6aSKATO Takenori /* 7604536af6aSKATO Takenori * There is no way to know wheter 15-16M hole exists or not. 7614536af6aSKATO Takenori * Therefore, we disable write allocate for this range. 7624536af6aSKATO Takenori */ 763925f3681SMike Smith whcr &= ~0x0001LL; 764925f3681SMike Smith #endif 765925f3681SMike Smith wrmsr(0x0c0000082, whcr); 766925f3681SMike Smith 767925f3681SMike Smith write_eflags(eflags); 768925f3681SMike Smith } 769925f3681SMike Smith 770925f3681SMike Smith void 771925f3681SMike Smith enable_K6_2_wt_alloc(void) 772925f3681SMike Smith { 773925f3681SMike Smith quad_t size; 774925f3681SMike Smith u_int64_t whcr; 775925f3681SMike Smith u_long eflags; 776925f3681SMike Smith 777925f3681SMike Smith eflags = read_eflags(); 778925f3681SMike Smith disable_intr(); 779925f3681SMike Smith wbinvd(); 780925f3681SMike Smith 781925f3681SMike Smith #ifdef CPU_DISABLE_CACHE 782925f3681SMike Smith /* 783925f3681SMike Smith * Certain K6-2 box becomes unstable when write allocation is 784925f3681SMike Smith * enabled. 785925f3681SMike Smith */ 786925f3681SMike Smith /* 787925f3681SMike Smith * The AMD-K6 processer provides the 64-bit Test Register 12(TR12), 788925f3681SMike Smith * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported. 789925f3681SMike Smith * All other bits in TR12 have no effect on the processer's operation. 790925f3681SMike Smith * The I/O Trap Restart function (bit 9 of TR12) is always enabled 791925f3681SMike Smith * on the AMD-K6. 792925f3681SMike Smith */ 793925f3681SMike Smith wrmsr(0x0000000e, (u_int64_t)0x0008); 794925f3681SMike Smith #endif 795925f3681SMike Smith /* Don't assume that memory size is aligned with 4M. */ 796925f3681SMike Smith if (Maxmem > 0) 797925f3681SMike Smith size = ((Maxmem >> 8) + 3) >> 2; 798925f3681SMike Smith else 799925f3681SMike Smith size = 0; 800925f3681SMike Smith 801925f3681SMike Smith /* Limit is 4092M bytes. */ 8024b055742SKATO Takenori if (size > 0x3fff) 8034b055742SKATO Takenori size = 0x3ff; 804925f3681SMike Smith whcr = (rdmsr(0xc0000082) & ~(0x3ffLL << 22)) | (size << 22); 805925f3681SMike Smith 806925f3681SMike Smith #if defined(PC98) || defined(NO_MEMORY_HOLE) 807925f3681SMike Smith if (whcr & (0x3ffLL << 22)) { 808925f3681SMike Smith #ifdef PC98 809925f3681SMike Smith /* 810925f3681SMike Smith * If bit 2 of port 0x43b is 0, disable wrte allocate for the 811925f3681SMike Smith * 15-16M range. 812925f3681SMike Smith */ 813925f3681SMike Smith if (!(inb(0x43b) & 4)) 814925f3681SMike Smith whcr &= ~(1LL << 16); 815925f3681SMike Smith else 816925f3681SMike Smith #endif 817925f3681SMike Smith whcr |= 1LL << 16; 818925f3681SMike Smith } 819925f3681SMike Smith #else 820925f3681SMike Smith /* 821925f3681SMike Smith * There is no way to know wheter 15-16M hole exists or not. 822925f3681SMike Smith * Therefore, we disable write allocate for this range. 823925f3681SMike Smith */ 824925f3681SMike Smith whcr &= ~(1LL << 16); 8254536af6aSKATO Takenori #endif 8264536af6aSKATO Takenori wrmsr(0x0c0000082, whcr); 8274536af6aSKATO Takenori 8284536af6aSKATO Takenori write_eflags(eflags); 8294536af6aSKATO Takenori } 8304536af6aSKATO Takenori #endif /* I585_CPU && CPU_WT_ALLOC */ 8314536af6aSKATO Takenori 832a8e282d6SKATO Takenori #include "opt_ddb.h" 833a8e282d6SKATO Takenori #ifdef DDB 834a8e282d6SKATO Takenori #include <ddb/ddb.h> 835a8e282d6SKATO Takenori 836a8e282d6SKATO Takenori DB_SHOW_COMMAND(cyrixreg, cyrixreg) 837a8e282d6SKATO Takenori { 838a8e282d6SKATO Takenori u_long eflags; 839a8e282d6SKATO Takenori u_int cr0; 8409402b520SMatthew Dillon u_char ccr1, ccr2, ccr3; 8419402b520SMatthew Dillon u_char ccr0 = 0, ccr4 = 0, ccr5 = 0, pcr0 = 0; 842a8e282d6SKATO Takenori 843a8e282d6SKATO Takenori cr0 = rcr0(); 844a8e282d6SKATO Takenori if (strcmp(cpu_vendor,"CyrixInstead") == 0) { 845a8e282d6SKATO Takenori eflags = read_eflags(); 846a8e282d6SKATO Takenori disable_intr(); 847a8e282d6SKATO Takenori 848a8e282d6SKATO Takenori 8499ca82267SKATO Takenori if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) { 850a8e282d6SKATO Takenori ccr0 = read_cyrix_reg(CCR0); 851a8e282d6SKATO Takenori } 852a8e282d6SKATO Takenori ccr1 = read_cyrix_reg(CCR1); 853a8e282d6SKATO Takenori ccr2 = read_cyrix_reg(CCR2); 854a8e282d6SKATO Takenori ccr3 = read_cyrix_reg(CCR3); 8556593be60SKATO Takenori if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) { 856a8e282d6SKATO Takenori write_cyrix_reg(CCR3, CCR3_MAPEN0); 857a8e282d6SKATO Takenori ccr4 = read_cyrix_reg(CCR4); 8586593be60SKATO Takenori if ((cpu == CPU_M1) || (cpu == CPU_M2)) 859a8e282d6SKATO Takenori ccr5 = read_cyrix_reg(CCR5); 860a8e282d6SKATO Takenori else 861a8e282d6SKATO Takenori pcr0 = read_cyrix_reg(PCR0); 862a8e282d6SKATO Takenori write_cyrix_reg(CCR3, ccr3); /* Restore CCR3. */ 863a8e282d6SKATO Takenori } 864a8e282d6SKATO Takenori write_eflags(eflags); 865a8e282d6SKATO Takenori 8669ca82267SKATO Takenori if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) 867a8e282d6SKATO Takenori printf("CCR0=%x, ", (u_int)ccr0); 868a8e282d6SKATO Takenori 869a8e282d6SKATO Takenori printf("CCR1=%x, CCR2=%x, CCR3=%x", 870a8e282d6SKATO Takenori (u_int)ccr1, (u_int)ccr2, (u_int)ccr3); 8716593be60SKATO Takenori if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) { 872a8e282d6SKATO Takenori printf(", CCR4=%x, ", (u_int)ccr4); 8736593be60SKATO Takenori if (cpu == CPU_M1SC) 874a8e282d6SKATO Takenori printf("PCR0=%x\n", pcr0); 8756593be60SKATO Takenori else 8766593be60SKATO Takenori printf("CCR5=%x\n", ccr5); 877a8e282d6SKATO Takenori } 878a8e282d6SKATO Takenori } 879a8e282d6SKATO Takenori printf("CR0=%x\n", cr0); 880a8e282d6SKATO Takenori } 881a8e282d6SKATO Takenori #endif /* DDB */ 882