1a8e282d6SKATO Takenori /* 2a8e282d6SKATO Takenori * Copyright (c) KATO Takenori, 1997. 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 * 296593be60SKATO Takenori * $Id: initcpu.c,v 1.7 1997/07/24 14:19:25 kato Exp $ 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> 37a8e282d6SKATO Takenori 38a8e282d6SKATO Takenori #include <machine/cpu.h> 39a8e282d6SKATO Takenori #include <machine/cputypes.h> 40a8e282d6SKATO Takenori #include <machine/md_var.h> 41a8e282d6SKATO Takenori #include <machine/specialreg.h> 42a8e282d6SKATO Takenori 43a8e282d6SKATO Takenori void initializecpu(void); 44a8e282d6SKATO Takenori #ifdef I486_CPU 45a8e282d6SKATO Takenori static void init_5x86(void); 46a8e282d6SKATO Takenori static void init_bluelightning(void); 47a8e282d6SKATO Takenori static void init_486dlc(void); 489ca82267SKATO Takenori static void init_cy486dx(void); 49a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386 50a8e282d6SKATO Takenori static void init_i486_on_386(void); 51a8e282d6SKATO Takenori #endif 52a8e282d6SKATO Takenori static void init_6x86(void); 53a8e282d6SKATO Takenori #endif /* I486_CPU */ 54a8e282d6SKATO Takenori 554877e978SKATO Takenori #ifdef I686_CPU 5620916c1fSKATO Takenori static void init_6x86MX(void); 5720916c1fSKATO Takenori #endif 5820916c1fSKATO Takenori 59a8e282d6SKATO Takenori #ifdef I486_CPU 60a8e282d6SKATO Takenori /* 61a8e282d6SKATO Takenori * IBM Blue Lightning 62a8e282d6SKATO Takenori */ 63a8e282d6SKATO Takenori static void 64a8e282d6SKATO Takenori init_bluelightning(void) 65a8e282d6SKATO Takenori { 66a8e282d6SKATO Takenori u_long eflags; 67a8e282d6SKATO Takenori 68a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) 69a8e282d6SKATO Takenori need_post_dma_flush = 1; 70a8e282d6SKATO Takenori #endif 71a8e282d6SKATO Takenori 72a8e282d6SKATO Takenori eflags = read_eflags(); 73a8e282d6SKATO Takenori disable_intr(); 74a8e282d6SKATO Takenori 75a8e282d6SKATO Takenori load_cr0(rcr0() | CR0_CD | CR0_NW); 76a8e282d6SKATO Takenori invd(); 77a8e282d6SKATO Takenori 78a8e282d6SKATO Takenori #ifdef CPU_BLUELIGHTNING_FPU_OP_CACHE 79a8e282d6SKATO Takenori wrmsr(0x1000, 0x9c92LL); /* FP operand can be cacheable on Cyrix FPU */ 80a8e282d6SKATO Takenori #else 81a8e282d6SKATO Takenori wrmsr(0x1000, 0x1c92LL); /* Intel FPU */ 82a8e282d6SKATO Takenori #endif 83a8e282d6SKATO Takenori /* Enables 13MB and 0-640KB cache. */ 84a8e282d6SKATO Takenori wrmsr(0x1001, (0xd0LL << 32) | 0x3ff); 85a8e282d6SKATO Takenori #ifdef CPU_BLUELIGHTNING_3X 86a8e282d6SKATO Takenori wrmsr(0x1002, 0x04000000LL); /* Enables triple-clock mode. */ 87a8e282d6SKATO Takenori #else 88a8e282d6SKATO Takenori wrmsr(0x1002, 0x03000000LL); /* Enables double-clock mode. */ 89a8e282d6SKATO Takenori #endif 90a8e282d6SKATO Takenori 91a8e282d6SKATO Takenori /* Enable caching in CR0. */ 92a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 93a8e282d6SKATO Takenori invd(); 94a8e282d6SKATO Takenori write_eflags(eflags); 95a8e282d6SKATO Takenori } 96a8e282d6SKATO Takenori 97a8e282d6SKATO Takenori /* 989ca82267SKATO Takenori * Cyrix 486SLC/DLC/SR/DR series 99a8e282d6SKATO Takenori */ 100a8e282d6SKATO Takenori static void 101a8e282d6SKATO Takenori init_486dlc(void) 102a8e282d6SKATO Takenori { 103a8e282d6SKATO Takenori u_long eflags; 104a8e282d6SKATO Takenori u_char ccr0; 105a8e282d6SKATO Takenori 106a8e282d6SKATO Takenori eflags = read_eflags(); 107a8e282d6SKATO Takenori disable_intr(); 108a8e282d6SKATO Takenori invd(); 109a8e282d6SKATO Takenori 110a8e282d6SKATO Takenori ccr0 = read_cyrix_reg(CCR0); 111a8e282d6SKATO Takenori #ifndef CYRIX_CACHE_WORKS 112a8e282d6SKATO Takenori ccr0 |= CCR0_NC1 | CCR0_BARB; 113a8e282d6SKATO Takenori write_cyrix_reg(CCR0, ccr0); 114a8e282d6SKATO Takenori invd(); 115a8e282d6SKATO Takenori #else 116a8e282d6SKATO Takenori ccr0 &= ~CCR0_NC0; 117a8e282d6SKATO Takenori #ifndef CYRIX_CACHE_REALLY_WORKS 118a8e282d6SKATO Takenori ccr0 |= CCR0_NC1 | CCR0_BARB; 119a8e282d6SKATO Takenori #else 120a8e282d6SKATO Takenori ccr0 |= CCR0_NC1; 121a8e282d6SKATO Takenori #endif 1224962d938SKATO Takenori #ifdef CPU_DIRECT_MAPPED_CACHE 1234962d938SKATO Takenori ccr0 |= CCR0_CO; /* Direct mapped mode. */ 1244962d938SKATO Takenori #endif 125a8e282d6SKATO Takenori write_cyrix_reg(CCR0, ccr0); 126a8e282d6SKATO Takenori 127a8e282d6SKATO Takenori /* Clear non-cacheable region. */ 128a8e282d6SKATO Takenori write_cyrix_reg(NCR1+2, NCR_SIZE_0K); 129a8e282d6SKATO Takenori write_cyrix_reg(NCR2+2, NCR_SIZE_0K); 130a8e282d6SKATO Takenori write_cyrix_reg(NCR3+2, NCR_SIZE_0K); 131a8e282d6SKATO Takenori write_cyrix_reg(NCR4+2, NCR_SIZE_0K); 132a8e282d6SKATO Takenori 133a8e282d6SKATO Takenori write_cyrix_reg(0, 0); /* dummy write */ 134a8e282d6SKATO Takenori 135a8e282d6SKATO Takenori /* Enable caching in CR0. */ 136a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 137a8e282d6SKATO Takenori invd(); 138a8e282d6SKATO Takenori #endif /* !CYRIX_CACHE_WORKS */ 139a8e282d6SKATO Takenori write_eflags(eflags); 140a8e282d6SKATO Takenori } 141a8e282d6SKATO Takenori 142a8e282d6SKATO Takenori 143a8e282d6SKATO Takenori /* 1449ca82267SKATO Takenori * Cyrix 486S/DX series 1459ca82267SKATO Takenori */ 1469ca82267SKATO Takenori static void 1479ca82267SKATO Takenori init_cy486dx(void) 1489ca82267SKATO Takenori { 1499ca82267SKATO Takenori u_long eflags; 1509ca82267SKATO Takenori u_char ccr2; 1519ca82267SKATO Takenori 1529ca82267SKATO Takenori eflags = read_eflags(); 1539ca82267SKATO Takenori disable_intr(); 1549ca82267SKATO Takenori invd(); 1559ca82267SKATO Takenori 1569ca82267SKATO Takenori ccr2 = read_cyrix_reg(CCR2); 1579ca82267SKATO Takenori #ifdef SUSP_HLT 1589ca82267SKATO Takenori ccr2 |= CCR2_SUSP_HTL; 1599ca82267SKATO Takenori #endif 1609ca82267SKATO Takenori write_cyrix_reg(CCR2, ccr2); 1619ca82267SKATO Takenori write_eflags(eflags); 1629ca82267SKATO Takenori } 1639ca82267SKATO Takenori 1649ca82267SKATO Takenori 1659ca82267SKATO Takenori /* 166a8e282d6SKATO Takenori * Cyrix 5x86 167a8e282d6SKATO Takenori */ 168a8e282d6SKATO Takenori static void 169a8e282d6SKATO Takenori init_5x86(void) 170a8e282d6SKATO Takenori { 171a8e282d6SKATO Takenori u_long eflags; 172a8e282d6SKATO Takenori u_char ccr2, ccr3, ccr4, pcr0; 173a8e282d6SKATO Takenori 174a8e282d6SKATO Takenori eflags = read_eflags(); 175a8e282d6SKATO Takenori disable_intr(); 176a8e282d6SKATO Takenori 177a8e282d6SKATO Takenori load_cr0(rcr0() | CR0_CD | CR0_NW); 178a8e282d6SKATO Takenori wbinvd(); 179a8e282d6SKATO Takenori 180a8e282d6SKATO Takenori (void)read_cyrix_reg(CCR3); /* dummy */ 181a8e282d6SKATO Takenori 182a8e282d6SKATO Takenori /* Initialize CCR2. */ 183a8e282d6SKATO Takenori ccr2 = read_cyrix_reg(CCR2); 184a8e282d6SKATO Takenori ccr2 |= CCR2_WB; 185a8e282d6SKATO Takenori #ifdef CPU_SUSP_HLT 186a8e282d6SKATO Takenori ccr2 |= CCR2_SUSP_HLT; 187a8e282d6SKATO Takenori #else 188a8e282d6SKATO Takenori ccr2 &= ~CCR2_SUSP_HLT; 189a8e282d6SKATO Takenori #endif 190a8e282d6SKATO Takenori ccr2 |= CCR2_WT1; 191a8e282d6SKATO Takenori write_cyrix_reg(CCR2, ccr2); 192a8e282d6SKATO Takenori 193a8e282d6SKATO Takenori /* Initialize CCR4. */ 194a8e282d6SKATO Takenori ccr3 = read_cyrix_reg(CCR3); 195a8e282d6SKATO Takenori write_cyrix_reg(CCR3, CCR3_MAPEN0); 196a8e282d6SKATO Takenori 197a8e282d6SKATO Takenori ccr4 = read_cyrix_reg(CCR4); 198a8e282d6SKATO Takenori ccr4 |= CCR4_DTE; 199a8e282d6SKATO Takenori ccr4 |= CCR4_MEM; 200a8e282d6SKATO Takenori #ifdef CPU_FASTER_5X86_FPU 201a8e282d6SKATO Takenori ccr4 |= CCR4_FASTFPE; 202a8e282d6SKATO Takenori #else 203a8e282d6SKATO Takenori ccr4 &= ~CCR4_FASTFPE; 204a8e282d6SKATO Takenori #endif 205a8e282d6SKATO Takenori ccr4 &= ~CCR4_IOMASK; 206a8e282d6SKATO Takenori /******************************************************************** 207a8e282d6SKATO Takenori * WARNING: The "BIOS Writers Guide" mentions that I/O recovery time 208a8e282d6SKATO Takenori * should be 0 for errata fix. 209a8e282d6SKATO Takenori ********************************************************************/ 210a8e282d6SKATO Takenori #ifdef CPU_IORT 211a8e282d6SKATO Takenori ccr4 |= CPU_IORT & CCR4_IOMASK; 212a8e282d6SKATO Takenori #endif 213a8e282d6SKATO Takenori write_cyrix_reg(CCR4, ccr4); 214a8e282d6SKATO Takenori 215a8e282d6SKATO Takenori /* Initialize PCR0. */ 216a8e282d6SKATO Takenori /**************************************************************** 217a8e282d6SKATO Takenori * WARNING: RSTK_EN and LOOP_EN could make your system unstable. 218a8e282d6SKATO Takenori * BTB_EN might make your system unstable. 219a8e282d6SKATO Takenori ****************************************************************/ 220a8e282d6SKATO Takenori pcr0 = read_cyrix_reg(PCR0); 221a8e282d6SKATO Takenori #ifdef CPU_RSTK_EN 222a8e282d6SKATO Takenori pcr0 |= PCR0_RSTK; 223a8e282d6SKATO Takenori #else 224a8e282d6SKATO Takenori pcr0 &= ~PCR0_RSTK; 225a8e282d6SKATO Takenori #endif 226a8e282d6SKATO Takenori #ifdef CPU_BTB_EN 227a8e282d6SKATO Takenori pcr0 |= PCR0_BTB; 228a8e282d6SKATO Takenori #else 229a8e282d6SKATO Takenori pcr0 &= ~PCR0_BTB; 230a8e282d6SKATO Takenori #endif 231a8e282d6SKATO Takenori #ifdef CPU_LOOP_EN 232a8e282d6SKATO Takenori pcr0 |= PCR0_LOOP; 233a8e282d6SKATO Takenori #else 234a8e282d6SKATO Takenori pcr0 &= ~PCR0_LOOP; 235a8e282d6SKATO Takenori #endif 236a8e282d6SKATO Takenori 237a8e282d6SKATO Takenori /**************************************************************** 238a8e282d6SKATO Takenori * WARNING: if you use a memory mapped I/O device, don't use 239a8e282d6SKATO Takenori * DISABLE_5X86_LSSER option, which may reorder memory mapped 240a8e282d6SKATO Takenori * I/O access. 241a8e282d6SKATO Takenori * IF YOUR MOTHERBOARD HAS PCI BUS, DON'T DISABLE LSSER. 242a8e282d6SKATO Takenori ****************************************************************/ 243a8e282d6SKATO Takenori #ifdef CPU_DISABLE_5X86_LSSER 244a8e282d6SKATO Takenori pcr0 &= ~PCR0_LSSER; 245a8e282d6SKATO Takenori #else 246a8e282d6SKATO Takenori pcr0 |= PCR0_LSSER; 247a8e282d6SKATO Takenori #endif 248a8e282d6SKATO Takenori write_cyrix_reg(PCR0, pcr0); 249a8e282d6SKATO Takenori 250a8e282d6SKATO Takenori /* Restore CCR3. */ 251a8e282d6SKATO Takenori write_cyrix_reg(CCR3, ccr3); 252a8e282d6SKATO Takenori 253a8e282d6SKATO Takenori (void)read_cyrix_reg(0x80); /* dummy */ 254a8e282d6SKATO Takenori 255a8e282d6SKATO Takenori /* Unlock NW bit in CR0. */ 256a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW); 257a8e282d6SKATO Takenori load_cr0((rcr0() & ~CR0_CD) | CR0_NW); /* CD = 0, NW = 1 */ 258a8e282d6SKATO Takenori /* Lock NW bit in CR0. */ 259a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW); 260a8e282d6SKATO Takenori 261a8e282d6SKATO Takenori write_eflags(eflags); 262a8e282d6SKATO Takenori } 263a8e282d6SKATO Takenori 264a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386 265a8e282d6SKATO Takenori /* 266a8e282d6SKATO Takenori * There are i486 based upgrade products for i386 machines. 267a8e282d6SKATO Takenori * In this case, BIOS doesn't enables CPU cache. 268a8e282d6SKATO Takenori */ 269a8e282d6SKATO Takenori void 270a8e282d6SKATO Takenori init_i486_on_386(void) 271a8e282d6SKATO Takenori { 272a8e282d6SKATO Takenori u_long eflags; 273a8e282d6SKATO Takenori 274a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) 275a8e282d6SKATO Takenori need_post_dma_flush = 1; 276a8e282d6SKATO Takenori #endif 277a8e282d6SKATO Takenori 278a8e282d6SKATO Takenori eflags = read_eflags(); 279a8e282d6SKATO Takenori disable_intr(); 280a8e282d6SKATO Takenori 281a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0, NW = 0 */ 282a8e282d6SKATO Takenori 2835fa4a058SKATO Takenori write_eflags(eflags); 284a8e282d6SKATO Takenori } 285a8e282d6SKATO Takenori #endif 286a8e282d6SKATO Takenori 287a8e282d6SKATO Takenori /* 288a8e282d6SKATO Takenori * Cyrix 6x86 289a8e282d6SKATO Takenori * 290a8e282d6SKATO Takenori * XXX - What should I do here? Please let me know. 291a8e282d6SKATO Takenori */ 292a8e282d6SKATO Takenori static void 293a8e282d6SKATO Takenori init_6x86(void) 294a8e282d6SKATO Takenori { 295a8e282d6SKATO Takenori u_long eflags; 296a8e282d6SKATO Takenori u_char ccr3, ccr4; 297a8e282d6SKATO Takenori 298a8e282d6SKATO Takenori eflags = read_eflags(); 299a8e282d6SKATO Takenori disable_intr(); 300a8e282d6SKATO Takenori 301a8e282d6SKATO Takenori load_cr0(rcr0() | CR0_CD | CR0_NW); 302a8e282d6SKATO Takenori wbinvd(); 303a8e282d6SKATO Takenori 304a8e282d6SKATO Takenori /* Initialize CCR0. */ 305a8e282d6SKATO Takenori write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1); 306a8e282d6SKATO Takenori 3076593be60SKATO Takenori /* Initialize CCR1. */ 3086593be60SKATO Takenori #ifdef CPU_CYRIX_NO_LOCK 3096593be60SKATO Takenori write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR1_NO_LOCK); 3106593be60SKATO Takenori #else 3116593be60SKATO Takenori #ifdef FAILSAFE 3126593be60SKATO Takenori write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) & ~CCR1_NO_LOCK); 3136593be60SKATO Takenori #endif 3146593be60SKATO Takenori #endif 3156593be60SKATO Takenori 316a8e282d6SKATO Takenori /* Initialize CCR2. */ 317a8e282d6SKATO Takenori #ifdef CPU_SUSP_HLT 318a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT); 319a8e282d6SKATO Takenori #else 320a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT); 321a8e282d6SKATO Takenori #endif 322a8e282d6SKATO Takenori 323a8e282d6SKATO Takenori ccr3 = read_cyrix_reg(CCR3); 324a8e282d6SKATO Takenori write_cyrix_reg(CCR3, CCR3_MAPEN0); 325a8e282d6SKATO Takenori 326a8e282d6SKATO Takenori /* Initialize CCR4. */ 327a8e282d6SKATO Takenori ccr4 = read_cyrix_reg(CCR4); 328a8e282d6SKATO Takenori ccr4 |= CCR4_DTE; 329a8e282d6SKATO Takenori ccr4 &= ~CCR4_IOMASK; 330a8e282d6SKATO Takenori #ifdef CPU_IORT 331a8e282d6SKATO Takenori write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK)); 332a8e282d6SKATO Takenori #else 333a8e282d6SKATO Takenori write_cyrix_reg(CCR4, ccr4 | 7); 334a8e282d6SKATO Takenori #endif 335a8e282d6SKATO Takenori 3366593be60SKATO Takenori /* Initialize CCR5. */ 3376593be60SKATO Takenori #ifdef CPU_WT_ALLOC 3386593be60SKATO Takenori write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC); 3396593be60SKATO Takenori #endif 3406593be60SKATO Takenori 341a8e282d6SKATO Takenori /* Restore CCR3. */ 342a8e282d6SKATO Takenori write_cyrix_reg(CCR3, ccr3); 343a8e282d6SKATO Takenori 344a8e282d6SKATO Takenori /* Unlock NW bit in CR0. */ 345a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW); 346a8e282d6SKATO Takenori 347a8e282d6SKATO Takenori /* 348a8e282d6SKATO Takenori * Earlier revision of the 6x86 CPU could crash the system if 349a8e282d6SKATO Takenori * L1 cache is in write-back mode. 350a8e282d6SKATO Takenori */ 351a8e282d6SKATO Takenori if ((cyrix_did & 0xff00) > 0x1600) 352a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 353a8e282d6SKATO Takenori else { 354a8e282d6SKATO Takenori /* Revision 2.6 and lower. */ 355a8e282d6SKATO Takenori #ifdef CYRIX_CACHE_REALLY_WORKS 356a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 357a8e282d6SKATO Takenori #else 358a8e282d6SKATO Takenori load_cr0((rcr0() & ~CR0_CD) | CR0_NW); /* CD = 0 and NW = 1 */ 359a8e282d6SKATO Takenori #endif 360a8e282d6SKATO Takenori } 361a8e282d6SKATO Takenori 362a8e282d6SKATO Takenori /* Lock NW bit in CR0. */ 363a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW); 364a8e282d6SKATO Takenori 365a8e282d6SKATO Takenori write_eflags(eflags); 366a8e282d6SKATO Takenori } 367a8e282d6SKATO Takenori #endif /* I486_CPU */ 368a8e282d6SKATO Takenori 3694877e978SKATO Takenori #ifdef I686_CPU 37020916c1fSKATO Takenori /* 37120916c1fSKATO Takenori * Cyrix 6x86MX (code-named M2) 37220916c1fSKATO Takenori * 37320916c1fSKATO Takenori * XXX - What should I do here? Please let me know. 37420916c1fSKATO Takenori */ 37520916c1fSKATO Takenori static void 37620916c1fSKATO Takenori init_6x86MX(void) 37720916c1fSKATO Takenori { 37820916c1fSKATO Takenori u_long eflags; 37920916c1fSKATO Takenori u_char ccr3, ccr4; 38020916c1fSKATO Takenori 38120916c1fSKATO Takenori eflags = read_eflags(); 38220916c1fSKATO Takenori disable_intr(); 38320916c1fSKATO Takenori 38420916c1fSKATO Takenori load_cr0(rcr0() | CR0_CD | CR0_NW); 38520916c1fSKATO Takenori wbinvd(); 38620916c1fSKATO Takenori 38720916c1fSKATO Takenori /* Initialize CCR0. */ 38820916c1fSKATO Takenori write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1); 38920916c1fSKATO Takenori 3906593be60SKATO Takenori /* Initialize CCR1. */ 3916593be60SKATO Takenori #ifdef CPU_CYRIX_NO_LOCK 3926593be60SKATO Takenori write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR1_NO_LOCK); 3936593be60SKATO Takenori #else 3946593be60SKATO Takenori #ifdef FAILSAFE 3956593be60SKATO Takenori write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) & ~CCR1_NO_LOCK); 3966593be60SKATO Takenori #endif 3976593be60SKATO Takenori #endif 3986593be60SKATO Takenori 39920916c1fSKATO Takenori /* Initialize CCR2. */ 40020916c1fSKATO Takenori #ifdef CPU_SUSP_HLT 40120916c1fSKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT); 40220916c1fSKATO Takenori #else 40320916c1fSKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT); 40420916c1fSKATO Takenori #endif 40520916c1fSKATO Takenori 40620916c1fSKATO Takenori ccr3 = read_cyrix_reg(CCR3); 40720916c1fSKATO Takenori write_cyrix_reg(CCR3, CCR3_MAPEN0); 40820916c1fSKATO Takenori 40920916c1fSKATO Takenori /* Initialize CCR4. */ 41020916c1fSKATO Takenori ccr4 = read_cyrix_reg(CCR4); 41120916c1fSKATO Takenori ccr4 &= ~CCR4_IOMASK; 41220916c1fSKATO Takenori #ifdef CPU_IORT 41320916c1fSKATO Takenori write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK)); 41420916c1fSKATO Takenori #else 41520916c1fSKATO Takenori write_cyrix_reg(CCR4, ccr4 | 7); 41620916c1fSKATO Takenori #endif 41720916c1fSKATO Takenori 4186593be60SKATO Takenori /* Initialize CCR5. */ 4196593be60SKATO Takenori #ifdef CPU_WT_ALLOC 4206593be60SKATO Takenori write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC); 4216593be60SKATO Takenori #endif 4226593be60SKATO Takenori 42320916c1fSKATO Takenori /* Restore CCR3. */ 42420916c1fSKATO Takenori write_cyrix_reg(CCR3, ccr3); 42520916c1fSKATO Takenori 42620916c1fSKATO Takenori /* Unlock NW bit in CR0. */ 42720916c1fSKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW); 42820916c1fSKATO Takenori 42920916c1fSKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 43020916c1fSKATO Takenori 43120916c1fSKATO Takenori /* Lock NW bit in CR0. */ 43220916c1fSKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW); 43320916c1fSKATO Takenori 43420916c1fSKATO Takenori write_eflags(eflags); 43520916c1fSKATO Takenori } 4364877e978SKATO Takenori #endif /* I686_CPU */ 43720916c1fSKATO Takenori 438a8e282d6SKATO Takenori void 439a8e282d6SKATO Takenori initializecpu(void) 440a8e282d6SKATO Takenori { 441a8e282d6SKATO Takenori 442a8e282d6SKATO Takenori switch (cpu) { 443a8e282d6SKATO Takenori #ifdef I486_CPU 444a8e282d6SKATO Takenori case CPU_BLUE: 445a8e282d6SKATO Takenori init_bluelightning(); 446a8e282d6SKATO Takenori break; 447a8e282d6SKATO Takenori case CPU_486DLC: 448a8e282d6SKATO Takenori init_486dlc(); 449a8e282d6SKATO Takenori break; 4509ca82267SKATO Takenori case CPU_CY486DX: 4519ca82267SKATO Takenori init_cy486dx(); 4529ca82267SKATO Takenori break; 453a8e282d6SKATO Takenori case CPU_M1SC: 454a8e282d6SKATO Takenori init_5x86(); 455a8e282d6SKATO Takenori break; 456a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386 457a8e282d6SKATO Takenori case CPU_486: 458a8e282d6SKATO Takenori init_i486_on_386(); 459a8e282d6SKATO Takenori break; 460a8e282d6SKATO Takenori #endif 461a8e282d6SKATO Takenori case CPU_M1: 462a8e282d6SKATO Takenori init_6x86(); 463a8e282d6SKATO Takenori break; 464a8e282d6SKATO Takenori #endif /* I486_CPU */ 4654877e978SKATO Takenori #ifdef I686_CPU 46620916c1fSKATO Takenori case CPU_M2: 46720916c1fSKATO Takenori init_6x86MX(); 46820916c1fSKATO Takenori break; 46920916c1fSKATO Takenori #endif 470a8e282d6SKATO Takenori default: 471a8e282d6SKATO Takenori break; 472a8e282d6SKATO Takenori } 473a8e282d6SKATO Takenori 474a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) 475a8e282d6SKATO Takenori /* 476a8e282d6SKATO Takenori * OS should flush L1 cahce by itself because no PC-98 supports 477a8e282d6SKATO Takenori * non-Intel CPUs. Use wbinvd instruction before DMA transfer 478a8e282d6SKATO Takenori * when need_pre_dma_flush = 1, use invd instruction after DMA 479a8e282d6SKATO Takenori * transfer when need_post_dma_flush = 1. If your CPU upgrade 480a8e282d6SKATO Takenori * product support hardware cache control, you can add 481a8e282d6SKATO Takenori * UPGRADE_CPU_HW_CACHE option in your kernel configuration file. 482a8e282d6SKATO Takenori * This option elminate unneeded cache flush instruction. 483a8e282d6SKATO Takenori */ 484a8e282d6SKATO Takenori if (strcmp(cpu_vendor, "CyrixInstead") == 0) { 485a8e282d6SKATO Takenori switch (cpu) { 486a8e282d6SKATO Takenori #ifdef I486_CPU 487a8e282d6SKATO Takenori case CPU_486DLC: 488a8e282d6SKATO Takenori need_post_dma_flush = 1; 489a8e282d6SKATO Takenori break; 490a8e282d6SKATO Takenori case CPU_M1SC: 491a8e282d6SKATO Takenori need_pre_dma_flush = 1; 492a8e282d6SKATO Takenori break; 493a8e282d6SKATO Takenori #endif 494a8e282d6SKATO Takenori default: 495a8e282d6SKATO Takenori break; 496a8e282d6SKATO Takenori } 497a8e282d6SKATO Takenori } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { 498a8e282d6SKATO Takenori switch (cpu_id & 0xFF0) { 499a8e282d6SKATO Takenori case 0x470: /* Enhanced Am486DX2 WB */ 500a8e282d6SKATO Takenori case 0x490: /* Enhanced Am486DX4 WB */ 501a8e282d6SKATO Takenori case 0x4F0: /* Am5x86 WB */ 502a8e282d6SKATO Takenori need_pre_dma_flush = 1; 503a8e282d6SKATO Takenori break; 504a8e282d6SKATO Takenori } 505a8e282d6SKATO Takenori } else if (strcmp(cpu_vendor, "IBM") == 0) { 506a8e282d6SKATO Takenori need_post_dma_flush = 1; 507a8e282d6SKATO Takenori } else { 508a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386 509a8e282d6SKATO Takenori need_pre_dma_flush = 1; 510a8e282d6SKATO Takenori #endif 511a8e282d6SKATO Takenori } 512a8e282d6SKATO Takenori #endif /* PC98 && !UPGRADE_CPU_HW_CACHE */ 513a8e282d6SKATO Takenori } 514a8e282d6SKATO Takenori 515a8e282d6SKATO Takenori #include "opt_ddb.h" 516a8e282d6SKATO Takenori #ifdef DDB 517a8e282d6SKATO Takenori #include <ddb/ddb.h> 518a8e282d6SKATO Takenori 519a8e282d6SKATO Takenori DB_SHOW_COMMAND(cyrixreg, cyrixreg) 520a8e282d6SKATO Takenori { 521a8e282d6SKATO Takenori u_long eflags; 522a8e282d6SKATO Takenori u_int cr0; 523a8e282d6SKATO Takenori u_char ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, pcr0; 524a8e282d6SKATO Takenori 525a8e282d6SKATO Takenori cr0 = rcr0(); 526a8e282d6SKATO Takenori if (strcmp(cpu_vendor,"CyrixInstead") == 0) { 527a8e282d6SKATO Takenori eflags = read_eflags(); 528a8e282d6SKATO Takenori disable_intr(); 529a8e282d6SKATO Takenori 530a8e282d6SKATO Takenori 5319ca82267SKATO Takenori if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) { 532a8e282d6SKATO Takenori ccr0 = read_cyrix_reg(CCR0); 533a8e282d6SKATO Takenori } 534a8e282d6SKATO Takenori ccr1 = read_cyrix_reg(CCR1); 535a8e282d6SKATO Takenori ccr2 = read_cyrix_reg(CCR2); 536a8e282d6SKATO Takenori ccr3 = read_cyrix_reg(CCR3); 5376593be60SKATO Takenori if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) { 538a8e282d6SKATO Takenori write_cyrix_reg(CCR3, CCR3_MAPEN0); 539a8e282d6SKATO Takenori ccr4 = read_cyrix_reg(CCR4); 5406593be60SKATO Takenori if ((cpu == CPU_M1) || (cpu == CPU_M2)) 541a8e282d6SKATO Takenori ccr5 = read_cyrix_reg(CCR5); 542a8e282d6SKATO Takenori else 543a8e282d6SKATO Takenori pcr0 = read_cyrix_reg(PCR0); 544a8e282d6SKATO Takenori write_cyrix_reg(CCR3, ccr3); /* Restore CCR3. */ 545a8e282d6SKATO Takenori } 546a8e282d6SKATO Takenori write_eflags(eflags); 547a8e282d6SKATO Takenori 5489ca82267SKATO Takenori if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) 549a8e282d6SKATO Takenori printf("CCR0=%x, ", (u_int)ccr0); 550a8e282d6SKATO Takenori 551a8e282d6SKATO Takenori printf("CCR1=%x, CCR2=%x, CCR3=%x", 552a8e282d6SKATO Takenori (u_int)ccr1, (u_int)ccr2, (u_int)ccr3); 5536593be60SKATO Takenori if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) { 554a8e282d6SKATO Takenori printf(", CCR4=%x, ", (u_int)ccr4); 5556593be60SKATO Takenori if (cpu == CPU_M1SC) 556a8e282d6SKATO Takenori printf("PCR0=%x\n", pcr0); 5576593be60SKATO Takenori else 5586593be60SKATO Takenori printf("CCR5=%x\n", ccr5); 559a8e282d6SKATO Takenori } 560a8e282d6SKATO Takenori } 561a8e282d6SKATO Takenori printf("CR0=%x\n", cr0); 562a8e282d6SKATO Takenori } 563a8e282d6SKATO Takenori #endif /* DDB */ 564