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> 37a8e282d6SKATO Takenori 38a8e282d6SKATO Takenori #include <machine/cputypes.h> 39a8e282d6SKATO Takenori #include <machine/md_var.h> 40a8e282d6SKATO Takenori #include <machine/specialreg.h> 41a8e282d6SKATO Takenori 42a8e282d6SKATO Takenori void initializecpu(void); 434536af6aSKATO Takenori #if defined(I586_CPU) && defined(CPU_WT_ALLOC) 444536af6aSKATO Takenori void enable_K5_wt_alloc(void); 454536af6aSKATO Takenori void enable_K6_wt_alloc(void); 46925f3681SMike Smith void enable_K6_2_wt_alloc(void); 474536af6aSKATO Takenori #endif 484536af6aSKATO Takenori 49a8e282d6SKATO Takenori #ifdef I486_CPU 50a8e282d6SKATO Takenori static void init_5x86(void); 51a8e282d6SKATO Takenori static void init_bluelightning(void); 52a8e282d6SKATO Takenori static void init_486dlc(void); 539ca82267SKATO Takenori static void init_cy486dx(void); 54a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386 55a8e282d6SKATO Takenori static void init_i486_on_386(void); 56a8e282d6SKATO Takenori #endif 57a8e282d6SKATO Takenori static void init_6x86(void); 58a8e282d6SKATO Takenori #endif /* I486_CPU */ 59a8e282d6SKATO Takenori 604877e978SKATO Takenori #ifdef I686_CPU 6120916c1fSKATO Takenori static void init_6x86MX(void); 620d303cbaSKATO Takenori static void init_ppro(void); 6365cbb03cSKATO Takenori static void init_mendocino(void); 6420916c1fSKATO Takenori #endif 6520916c1fSKATO Takenori 66a8e282d6SKATO Takenori #ifdef I486_CPU 67a8e282d6SKATO Takenori /* 68a8e282d6SKATO Takenori * IBM Blue Lightning 69a8e282d6SKATO Takenori */ 70a8e282d6SKATO Takenori static void 71a8e282d6SKATO Takenori init_bluelightning(void) 72a8e282d6SKATO Takenori { 73a8e282d6SKATO Takenori u_long eflags; 74a8e282d6SKATO Takenori 75a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) 76a8e282d6SKATO Takenori need_post_dma_flush = 1; 77a8e282d6SKATO Takenori #endif 78a8e282d6SKATO Takenori 79a8e282d6SKATO Takenori eflags = read_eflags(); 80a8e282d6SKATO Takenori disable_intr(); 81a8e282d6SKATO Takenori 82a8e282d6SKATO Takenori load_cr0(rcr0() | CR0_CD | CR0_NW); 83a8e282d6SKATO Takenori invd(); 84a8e282d6SKATO Takenori 85a8e282d6SKATO Takenori #ifdef CPU_BLUELIGHTNING_FPU_OP_CACHE 86a8e282d6SKATO Takenori wrmsr(0x1000, 0x9c92LL); /* FP operand can be cacheable on Cyrix FPU */ 87a8e282d6SKATO Takenori #else 88a8e282d6SKATO Takenori wrmsr(0x1000, 0x1c92LL); /* Intel FPU */ 89a8e282d6SKATO Takenori #endif 90a8e282d6SKATO Takenori /* Enables 13MB and 0-640KB cache. */ 91a8e282d6SKATO Takenori wrmsr(0x1001, (0xd0LL << 32) | 0x3ff); 92a8e282d6SKATO Takenori #ifdef CPU_BLUELIGHTNING_3X 93a8e282d6SKATO Takenori wrmsr(0x1002, 0x04000000LL); /* Enables triple-clock mode. */ 94a8e282d6SKATO Takenori #else 95a8e282d6SKATO Takenori wrmsr(0x1002, 0x03000000LL); /* Enables double-clock mode. */ 96a8e282d6SKATO Takenori #endif 97a8e282d6SKATO Takenori 98a8e282d6SKATO Takenori /* Enable caching in CR0. */ 99a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 100a8e282d6SKATO Takenori invd(); 101a8e282d6SKATO Takenori write_eflags(eflags); 102a8e282d6SKATO Takenori } 103a8e282d6SKATO Takenori 104a8e282d6SKATO Takenori /* 1059ca82267SKATO Takenori * Cyrix 486SLC/DLC/SR/DR series 106a8e282d6SKATO Takenori */ 107a8e282d6SKATO Takenori static void 108a8e282d6SKATO Takenori init_486dlc(void) 109a8e282d6SKATO Takenori { 110a8e282d6SKATO Takenori u_long eflags; 111a8e282d6SKATO Takenori u_char ccr0; 112a8e282d6SKATO Takenori 113a8e282d6SKATO Takenori eflags = read_eflags(); 114a8e282d6SKATO Takenori disable_intr(); 115a8e282d6SKATO Takenori invd(); 116a8e282d6SKATO Takenori 117a8e282d6SKATO Takenori ccr0 = read_cyrix_reg(CCR0); 118a8e282d6SKATO Takenori #ifndef CYRIX_CACHE_WORKS 119a8e282d6SKATO Takenori ccr0 |= CCR0_NC1 | CCR0_BARB; 120a8e282d6SKATO Takenori write_cyrix_reg(CCR0, ccr0); 121a8e282d6SKATO Takenori invd(); 122a8e282d6SKATO Takenori #else 123a8e282d6SKATO Takenori ccr0 &= ~CCR0_NC0; 124a8e282d6SKATO Takenori #ifndef CYRIX_CACHE_REALLY_WORKS 125a8e282d6SKATO Takenori ccr0 |= CCR0_NC1 | CCR0_BARB; 126a8e282d6SKATO Takenori #else 127a8e282d6SKATO Takenori ccr0 |= CCR0_NC1; 128a8e282d6SKATO Takenori #endif 1294962d938SKATO Takenori #ifdef CPU_DIRECT_MAPPED_CACHE 1304962d938SKATO Takenori ccr0 |= CCR0_CO; /* Direct mapped mode. */ 1314962d938SKATO Takenori #endif 132a8e282d6SKATO Takenori write_cyrix_reg(CCR0, ccr0); 133a8e282d6SKATO Takenori 134a8e282d6SKATO Takenori /* Clear non-cacheable region. */ 135a8e282d6SKATO Takenori write_cyrix_reg(NCR1+2, NCR_SIZE_0K); 136a8e282d6SKATO Takenori write_cyrix_reg(NCR2+2, NCR_SIZE_0K); 137a8e282d6SKATO Takenori write_cyrix_reg(NCR3+2, NCR_SIZE_0K); 138a8e282d6SKATO Takenori write_cyrix_reg(NCR4+2, NCR_SIZE_0K); 139a8e282d6SKATO Takenori 140a8e282d6SKATO Takenori write_cyrix_reg(0, 0); /* dummy write */ 141a8e282d6SKATO Takenori 142a8e282d6SKATO Takenori /* Enable caching in CR0. */ 143a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 144a8e282d6SKATO Takenori invd(); 145a8e282d6SKATO Takenori #endif /* !CYRIX_CACHE_WORKS */ 146a8e282d6SKATO Takenori write_eflags(eflags); 147a8e282d6SKATO Takenori } 148a8e282d6SKATO Takenori 149a8e282d6SKATO Takenori 150a8e282d6SKATO Takenori /* 1519ca82267SKATO Takenori * Cyrix 486S/DX series 1529ca82267SKATO Takenori */ 1539ca82267SKATO Takenori static void 1549ca82267SKATO Takenori init_cy486dx(void) 1559ca82267SKATO Takenori { 1569ca82267SKATO Takenori u_long eflags; 1579ca82267SKATO Takenori u_char ccr2; 1589ca82267SKATO Takenori 1599ca82267SKATO Takenori eflags = read_eflags(); 1609ca82267SKATO Takenori disable_intr(); 1619ca82267SKATO Takenori invd(); 1629ca82267SKATO Takenori 1639ca82267SKATO Takenori ccr2 = read_cyrix_reg(CCR2); 1641ba2a543SKATO Takenori #ifdef CPU_SUSP_HLT 1651ba2a543SKATO Takenori ccr2 |= CCR2_SUSP_HLT; 1669ca82267SKATO Takenori #endif 1671cfd836fSKATO Takenori 1681cfd836fSKATO Takenori #ifdef PC98 1691cfd836fSKATO Takenori /* Enables WB cache interface pin and Lock NW bit in CR0. */ 1701cfd836fSKATO Takenori ccr2 |= CCR2_WB | CCR2_LOCK_NW; 1711cfd836fSKATO Takenori /* Unlock NW bit in CR0. */ 1721cfd836fSKATO Takenori write_cyrix_reg(CCR2, ccr2 & ~CCR2_LOCK_NW); 1731cfd836fSKATO Takenori load_cr0((rcr0() & ~CR0_CD) | CR0_NW); /* CD = 0, NW = 1 */ 1741cfd836fSKATO Takenori #endif 1751cfd836fSKATO Takenori 1769ca82267SKATO Takenori write_cyrix_reg(CCR2, ccr2); 1779ca82267SKATO Takenori write_eflags(eflags); 1789ca82267SKATO Takenori } 1799ca82267SKATO Takenori 1809ca82267SKATO Takenori 1819ca82267SKATO Takenori /* 182a8e282d6SKATO Takenori * Cyrix 5x86 183a8e282d6SKATO Takenori */ 184a8e282d6SKATO Takenori static void 185a8e282d6SKATO Takenori init_5x86(void) 186a8e282d6SKATO Takenori { 187a8e282d6SKATO Takenori u_long eflags; 188a8e282d6SKATO Takenori u_char ccr2, ccr3, ccr4, pcr0; 189a8e282d6SKATO Takenori 190a8e282d6SKATO Takenori eflags = read_eflags(); 191a8e282d6SKATO Takenori disable_intr(); 192a8e282d6SKATO Takenori 193a8e282d6SKATO Takenori load_cr0(rcr0() | CR0_CD | CR0_NW); 194a8e282d6SKATO Takenori wbinvd(); 195a8e282d6SKATO Takenori 196a8e282d6SKATO Takenori (void)read_cyrix_reg(CCR3); /* dummy */ 197a8e282d6SKATO Takenori 198a8e282d6SKATO Takenori /* Initialize CCR2. */ 199a8e282d6SKATO Takenori ccr2 = read_cyrix_reg(CCR2); 200a8e282d6SKATO Takenori ccr2 |= CCR2_WB; 201a8e282d6SKATO Takenori #ifdef CPU_SUSP_HLT 202a8e282d6SKATO Takenori ccr2 |= CCR2_SUSP_HLT; 203a8e282d6SKATO Takenori #else 204a8e282d6SKATO Takenori ccr2 &= ~CCR2_SUSP_HLT; 205a8e282d6SKATO Takenori #endif 206a8e282d6SKATO Takenori ccr2 |= CCR2_WT1; 207a8e282d6SKATO Takenori write_cyrix_reg(CCR2, ccr2); 208a8e282d6SKATO Takenori 209a8e282d6SKATO Takenori /* Initialize CCR4. */ 210a8e282d6SKATO Takenori ccr3 = read_cyrix_reg(CCR3); 211a8e282d6SKATO Takenori write_cyrix_reg(CCR3, CCR3_MAPEN0); 212a8e282d6SKATO Takenori 213a8e282d6SKATO Takenori ccr4 = read_cyrix_reg(CCR4); 214a8e282d6SKATO Takenori ccr4 |= CCR4_DTE; 215a8e282d6SKATO Takenori ccr4 |= CCR4_MEM; 216a8e282d6SKATO Takenori #ifdef CPU_FASTER_5X86_FPU 217a8e282d6SKATO Takenori ccr4 |= CCR4_FASTFPE; 218a8e282d6SKATO Takenori #else 219a8e282d6SKATO Takenori ccr4 &= ~CCR4_FASTFPE; 220a8e282d6SKATO Takenori #endif 221a8e282d6SKATO Takenori ccr4 &= ~CCR4_IOMASK; 222a8e282d6SKATO Takenori /******************************************************************** 223a8e282d6SKATO Takenori * WARNING: The "BIOS Writers Guide" mentions that I/O recovery time 224a8e282d6SKATO Takenori * should be 0 for errata fix. 225a8e282d6SKATO Takenori ********************************************************************/ 226a8e282d6SKATO Takenori #ifdef CPU_IORT 227a8e282d6SKATO Takenori ccr4 |= CPU_IORT & CCR4_IOMASK; 228a8e282d6SKATO Takenori #endif 229a8e282d6SKATO Takenori write_cyrix_reg(CCR4, ccr4); 230a8e282d6SKATO Takenori 231a8e282d6SKATO Takenori /* Initialize PCR0. */ 232a8e282d6SKATO Takenori /**************************************************************** 233a8e282d6SKATO Takenori * WARNING: RSTK_EN and LOOP_EN could make your system unstable. 234a8e282d6SKATO Takenori * BTB_EN might make your system unstable. 235a8e282d6SKATO Takenori ****************************************************************/ 236a8e282d6SKATO Takenori pcr0 = read_cyrix_reg(PCR0); 237a8e282d6SKATO Takenori #ifdef CPU_RSTK_EN 238a8e282d6SKATO Takenori pcr0 |= PCR0_RSTK; 239a8e282d6SKATO Takenori #else 240a8e282d6SKATO Takenori pcr0 &= ~PCR0_RSTK; 241a8e282d6SKATO Takenori #endif 242a8e282d6SKATO Takenori #ifdef CPU_BTB_EN 243a8e282d6SKATO Takenori pcr0 |= PCR0_BTB; 244a8e282d6SKATO Takenori #else 245a8e282d6SKATO Takenori pcr0 &= ~PCR0_BTB; 246a8e282d6SKATO Takenori #endif 247a8e282d6SKATO Takenori #ifdef CPU_LOOP_EN 248a8e282d6SKATO Takenori pcr0 |= PCR0_LOOP; 249a8e282d6SKATO Takenori #else 250a8e282d6SKATO Takenori pcr0 &= ~PCR0_LOOP; 251a8e282d6SKATO Takenori #endif 252a8e282d6SKATO Takenori 253a8e282d6SKATO Takenori /**************************************************************** 254a8e282d6SKATO Takenori * WARNING: if you use a memory mapped I/O device, don't use 255a8e282d6SKATO Takenori * DISABLE_5X86_LSSER option, which may reorder memory mapped 256a8e282d6SKATO Takenori * I/O access. 257a8e282d6SKATO Takenori * IF YOUR MOTHERBOARD HAS PCI BUS, DON'T DISABLE LSSER. 258a8e282d6SKATO Takenori ****************************************************************/ 259a8e282d6SKATO Takenori #ifdef CPU_DISABLE_5X86_LSSER 260a8e282d6SKATO Takenori pcr0 &= ~PCR0_LSSER; 261a8e282d6SKATO Takenori #else 262a8e282d6SKATO Takenori pcr0 |= PCR0_LSSER; 263a8e282d6SKATO Takenori #endif 264a8e282d6SKATO Takenori write_cyrix_reg(PCR0, pcr0); 265a8e282d6SKATO Takenori 266a8e282d6SKATO Takenori /* Restore CCR3. */ 267a8e282d6SKATO Takenori write_cyrix_reg(CCR3, ccr3); 268a8e282d6SKATO Takenori 269a8e282d6SKATO Takenori (void)read_cyrix_reg(0x80); /* dummy */ 270a8e282d6SKATO Takenori 271a8e282d6SKATO Takenori /* Unlock NW bit in CR0. */ 272a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW); 273a8e282d6SKATO Takenori load_cr0((rcr0() & ~CR0_CD) | CR0_NW); /* CD = 0, NW = 1 */ 274a8e282d6SKATO Takenori /* Lock NW bit in CR0. */ 275a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW); 276a8e282d6SKATO Takenori 277a8e282d6SKATO Takenori write_eflags(eflags); 278a8e282d6SKATO Takenori } 279a8e282d6SKATO Takenori 280a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386 281a8e282d6SKATO Takenori /* 282a8e282d6SKATO Takenori * There are i486 based upgrade products for i386 machines. 283a8e282d6SKATO Takenori * In this case, BIOS doesn't enables CPU cache. 284a8e282d6SKATO Takenori */ 285a8e282d6SKATO Takenori void 286a8e282d6SKATO Takenori init_i486_on_386(void) 287a8e282d6SKATO Takenori { 288a8e282d6SKATO Takenori u_long eflags; 289a8e282d6SKATO Takenori 290a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) 291a8e282d6SKATO Takenori need_post_dma_flush = 1; 292a8e282d6SKATO Takenori #endif 293a8e282d6SKATO Takenori 294a8e282d6SKATO Takenori eflags = read_eflags(); 295a8e282d6SKATO Takenori disable_intr(); 296a8e282d6SKATO Takenori 297a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0, NW = 0 */ 298a8e282d6SKATO Takenori 2995fa4a058SKATO Takenori write_eflags(eflags); 300a8e282d6SKATO Takenori } 301a8e282d6SKATO Takenori #endif 302a8e282d6SKATO Takenori 303a8e282d6SKATO Takenori /* 304a8e282d6SKATO Takenori * Cyrix 6x86 305a8e282d6SKATO Takenori * 306a8e282d6SKATO Takenori * XXX - What should I do here? Please let me know. 307a8e282d6SKATO Takenori */ 308a8e282d6SKATO Takenori static void 309a8e282d6SKATO Takenori init_6x86(void) 310a8e282d6SKATO Takenori { 311a8e282d6SKATO Takenori u_long eflags; 312a8e282d6SKATO Takenori u_char ccr3, ccr4; 313a8e282d6SKATO Takenori 314a8e282d6SKATO Takenori eflags = read_eflags(); 315a8e282d6SKATO Takenori disable_intr(); 316a8e282d6SKATO Takenori 317a8e282d6SKATO Takenori load_cr0(rcr0() | CR0_CD | CR0_NW); 318a8e282d6SKATO Takenori wbinvd(); 319a8e282d6SKATO Takenori 320a8e282d6SKATO Takenori /* Initialize CCR0. */ 321a8e282d6SKATO Takenori write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1); 322a8e282d6SKATO Takenori 3236593be60SKATO Takenori /* Initialize CCR1. */ 3246593be60SKATO Takenori #ifdef CPU_CYRIX_NO_LOCK 325b20f1ceeSJonathan Lemon write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK); 3266593be60SKATO Takenori #else 327b20f1ceeSJonathan Lemon write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK); 3286593be60SKATO Takenori #endif 3296593be60SKATO Takenori 330a8e282d6SKATO Takenori /* Initialize CCR2. */ 331a8e282d6SKATO Takenori #ifdef CPU_SUSP_HLT 332a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT); 333a8e282d6SKATO Takenori #else 334a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT); 335a8e282d6SKATO Takenori #endif 336a8e282d6SKATO Takenori 337a8e282d6SKATO Takenori ccr3 = read_cyrix_reg(CCR3); 338a8e282d6SKATO Takenori write_cyrix_reg(CCR3, CCR3_MAPEN0); 339a8e282d6SKATO Takenori 340a8e282d6SKATO Takenori /* Initialize CCR4. */ 341a8e282d6SKATO Takenori ccr4 = read_cyrix_reg(CCR4); 342a8e282d6SKATO Takenori ccr4 |= CCR4_DTE; 343a8e282d6SKATO Takenori ccr4 &= ~CCR4_IOMASK; 344a8e282d6SKATO Takenori #ifdef CPU_IORT 345a8e282d6SKATO Takenori write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK)); 346a8e282d6SKATO Takenori #else 347a8e282d6SKATO Takenori write_cyrix_reg(CCR4, ccr4 | 7); 348a8e282d6SKATO Takenori #endif 349a8e282d6SKATO Takenori 3506593be60SKATO Takenori /* Initialize CCR5. */ 3516593be60SKATO Takenori #ifdef CPU_WT_ALLOC 3526593be60SKATO Takenori write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC); 3536593be60SKATO Takenori #endif 3546593be60SKATO Takenori 355a8e282d6SKATO Takenori /* Restore CCR3. */ 356a8e282d6SKATO Takenori write_cyrix_reg(CCR3, ccr3); 357a8e282d6SKATO Takenori 358a8e282d6SKATO Takenori /* Unlock NW bit in CR0. */ 359a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW); 360a8e282d6SKATO Takenori 361a8e282d6SKATO Takenori /* 362a8e282d6SKATO Takenori * Earlier revision of the 6x86 CPU could crash the system if 363a8e282d6SKATO Takenori * L1 cache is in write-back mode. 364a8e282d6SKATO Takenori */ 365a8e282d6SKATO Takenori if ((cyrix_did & 0xff00) > 0x1600) 366a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 367a8e282d6SKATO Takenori else { 368a8e282d6SKATO Takenori /* Revision 2.6 and lower. */ 369a8e282d6SKATO Takenori #ifdef CYRIX_CACHE_REALLY_WORKS 370a8e282d6SKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 371a8e282d6SKATO Takenori #else 372a8e282d6SKATO Takenori load_cr0((rcr0() & ~CR0_CD) | CR0_NW); /* CD = 0 and NW = 1 */ 373a8e282d6SKATO Takenori #endif 374a8e282d6SKATO Takenori } 375a8e282d6SKATO Takenori 376a8e282d6SKATO Takenori /* Lock NW bit in CR0. */ 377a8e282d6SKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW); 378a8e282d6SKATO Takenori 379a8e282d6SKATO Takenori write_eflags(eflags); 380a8e282d6SKATO Takenori } 381a8e282d6SKATO Takenori #endif /* I486_CPU */ 382a8e282d6SKATO Takenori 3834877e978SKATO Takenori #ifdef I686_CPU 38420916c1fSKATO Takenori /* 38520916c1fSKATO Takenori * Cyrix 6x86MX (code-named M2) 38620916c1fSKATO Takenori * 38720916c1fSKATO Takenori * XXX - What should I do here? Please let me know. 38820916c1fSKATO Takenori */ 38920916c1fSKATO Takenori static void 39020916c1fSKATO Takenori init_6x86MX(void) 39120916c1fSKATO Takenori { 39220916c1fSKATO Takenori u_long eflags; 39320916c1fSKATO Takenori u_char ccr3, ccr4; 39420916c1fSKATO Takenori 39520916c1fSKATO Takenori eflags = read_eflags(); 39620916c1fSKATO Takenori disable_intr(); 39720916c1fSKATO Takenori 39820916c1fSKATO Takenori load_cr0(rcr0() | CR0_CD | CR0_NW); 39920916c1fSKATO Takenori wbinvd(); 40020916c1fSKATO Takenori 40120916c1fSKATO Takenori /* Initialize CCR0. */ 40220916c1fSKATO Takenori write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1); 40320916c1fSKATO Takenori 4046593be60SKATO Takenori /* Initialize CCR1. */ 4056593be60SKATO Takenori #ifdef CPU_CYRIX_NO_LOCK 406b20f1ceeSJonathan Lemon write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK); 4076593be60SKATO Takenori #else 408b20f1ceeSJonathan Lemon write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK); 4096593be60SKATO Takenori #endif 4106593be60SKATO Takenori 41120916c1fSKATO Takenori /* Initialize CCR2. */ 41220916c1fSKATO Takenori #ifdef CPU_SUSP_HLT 41320916c1fSKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT); 41420916c1fSKATO Takenori #else 41520916c1fSKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT); 41620916c1fSKATO Takenori #endif 41720916c1fSKATO Takenori 41820916c1fSKATO Takenori ccr3 = read_cyrix_reg(CCR3); 41920916c1fSKATO Takenori write_cyrix_reg(CCR3, CCR3_MAPEN0); 42020916c1fSKATO Takenori 42120916c1fSKATO Takenori /* Initialize CCR4. */ 42220916c1fSKATO Takenori ccr4 = read_cyrix_reg(CCR4); 42320916c1fSKATO Takenori ccr4 &= ~CCR4_IOMASK; 42420916c1fSKATO Takenori #ifdef CPU_IORT 42520916c1fSKATO Takenori write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK)); 42620916c1fSKATO Takenori #else 42720916c1fSKATO Takenori write_cyrix_reg(CCR4, ccr4 | 7); 42820916c1fSKATO Takenori #endif 42920916c1fSKATO Takenori 4306593be60SKATO Takenori /* Initialize CCR5. */ 4316593be60SKATO Takenori #ifdef CPU_WT_ALLOC 4326593be60SKATO Takenori write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC); 4336593be60SKATO Takenori #endif 4346593be60SKATO Takenori 43520916c1fSKATO Takenori /* Restore CCR3. */ 43620916c1fSKATO Takenori write_cyrix_reg(CCR3, ccr3); 43720916c1fSKATO Takenori 43820916c1fSKATO Takenori /* Unlock NW bit in CR0. */ 43920916c1fSKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW); 44020916c1fSKATO Takenori 44120916c1fSKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ 44220916c1fSKATO Takenori 44320916c1fSKATO Takenori /* Lock NW bit in CR0. */ 44420916c1fSKATO Takenori write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW); 44520916c1fSKATO Takenori 44620916c1fSKATO Takenori write_eflags(eflags); 44720916c1fSKATO Takenori } 4480d303cbaSKATO Takenori 4490d303cbaSKATO Takenori static void 4500d303cbaSKATO Takenori init_ppro(void) 4510d303cbaSKATO Takenori { 4520d303cbaSKATO Takenori #ifndef SMP 4534536af6aSKATO Takenori u_int64_t apicbase; 4540d303cbaSKATO Takenori 4550d303cbaSKATO Takenori /* 4560d303cbaSKATO Takenori * Local APIC should be diabled in UP kernel. 4570d303cbaSKATO Takenori */ 4580d303cbaSKATO Takenori apicbase = rdmsr(0x1b); 4590d303cbaSKATO Takenori apicbase &= ~0x800LL; 4600d303cbaSKATO Takenori wrmsr(0x1b, apicbase); 4610d303cbaSKATO Takenori #endif 4620d303cbaSKATO Takenori } 46365cbb03cSKATO Takenori 46465cbb03cSKATO Takenori /* 46565cbb03cSKATO Takenori * Initialize BBL_CR_CTL3 (Control register 3: used to configure the 46665cbb03cSKATO Takenori * L2 cache). 46765cbb03cSKATO Takenori */ 46865cbb03cSKATO Takenori void 46965cbb03cSKATO Takenori init_mendocino(void) 47065cbb03cSKATO Takenori { 47165cbb03cSKATO Takenori #ifdef CPU_PPRO2CELERON 47265cbb03cSKATO Takenori u_long eflags; 47365cbb03cSKATO Takenori u_int64_t bbl_cr_ctl3; 47465cbb03cSKATO Takenori 47565cbb03cSKATO Takenori eflags = read_eflags(); 47665cbb03cSKATO Takenori disable_intr(); 47765cbb03cSKATO Takenori 47865cbb03cSKATO Takenori load_cr0(rcr0() | CR0_CD | CR0_NW); 47965cbb03cSKATO Takenori wbinvd(); 48065cbb03cSKATO Takenori 48165cbb03cSKATO Takenori bbl_cr_ctl3 = rdmsr(0x11e); 48265cbb03cSKATO Takenori 48365cbb03cSKATO Takenori /* If the L2 cache is configured, do nothing. */ 48465cbb03cSKATO Takenori if (!(bbl_cr_ctl3 & 1)) { 48565cbb03cSKATO Takenori bbl_cr_ctl3 = 0x134052bLL; 48665cbb03cSKATO Takenori 48765cbb03cSKATO Takenori /* Set L2 Cache Latency (Default: 5). */ 48865cbb03cSKATO Takenori #ifdef CPU_CELERON_L2_LATENCY 48965cbb03cSKATO Takenori #if CPU_L2_LATENCY > 15 49065cbb03cSKATO Takenori #error invalid CPU_L2_LATENCY. 49165cbb03cSKATO Takenori #endif 49265cbb03cSKATO Takenori bbl_cr_ctl3 |= CPU_L2_LATENCY << 1; 49365cbb03cSKATO Takenori #else 49465cbb03cSKATO Takenori bbl_cr_ctl3 |= 5 << 1; 49565cbb03cSKATO Takenori #endif 49665cbb03cSKATO Takenori wrmsr(0x11e, bbl_cr_ctl3); 49765cbb03cSKATO Takenori } 49865cbb03cSKATO Takenori 49965cbb03cSKATO Takenori load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); 50065cbb03cSKATO Takenori write_eflags(eflags); 50165cbb03cSKATO Takenori #endif /* CPU_PPRO2CELERON */ 50265cbb03cSKATO Takenori } 50365cbb03cSKATO Takenori 5044877e978SKATO Takenori #endif /* I686_CPU */ 50520916c1fSKATO Takenori 506a8e282d6SKATO Takenori void 507a8e282d6SKATO Takenori initializecpu(void) 508a8e282d6SKATO Takenori { 509a8e282d6SKATO Takenori 510a8e282d6SKATO Takenori switch (cpu) { 511a8e282d6SKATO Takenori #ifdef I486_CPU 512a8e282d6SKATO Takenori case CPU_BLUE: 513a8e282d6SKATO Takenori init_bluelightning(); 514a8e282d6SKATO Takenori break; 515a8e282d6SKATO Takenori case CPU_486DLC: 516a8e282d6SKATO Takenori init_486dlc(); 517a8e282d6SKATO Takenori break; 5189ca82267SKATO Takenori case CPU_CY486DX: 5199ca82267SKATO Takenori init_cy486dx(); 5209ca82267SKATO Takenori break; 521a8e282d6SKATO Takenori case CPU_M1SC: 522a8e282d6SKATO Takenori init_5x86(); 523a8e282d6SKATO Takenori break; 524a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386 525a8e282d6SKATO Takenori case CPU_486: 526a8e282d6SKATO Takenori init_i486_on_386(); 527a8e282d6SKATO Takenori break; 528a8e282d6SKATO Takenori #endif 529a8e282d6SKATO Takenori case CPU_M1: 530a8e282d6SKATO Takenori init_6x86(); 531a8e282d6SKATO Takenori break; 532a8e282d6SKATO Takenori #endif /* I486_CPU */ 5334877e978SKATO Takenori #ifdef I686_CPU 53420916c1fSKATO Takenori case CPU_M2: 53520916c1fSKATO Takenori init_6x86MX(); 53620916c1fSKATO Takenori break; 5370d303cbaSKATO Takenori case CPU_686: 53865cbb03cSKATO Takenori if (strcmp(cpu_vendor, "GenuineIntel") == 0) { 53965cbb03cSKATO Takenori switch (cpu_id & 0xff0) { 54065cbb03cSKATO Takenori case 0x610: 5410d303cbaSKATO Takenori init_ppro(); 5420d303cbaSKATO Takenori break; 54365cbb03cSKATO Takenori case 0x660: 54465cbb03cSKATO Takenori init_mendocino(); 54565cbb03cSKATO Takenori break; 54665cbb03cSKATO Takenori } 54765cbb03cSKATO Takenori } 54865cbb03cSKATO Takenori break; 54920916c1fSKATO Takenori #endif 550a8e282d6SKATO Takenori default: 551a8e282d6SKATO Takenori break; 552a8e282d6SKATO Takenori } 553a8e282d6SKATO Takenori 554a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) 555a8e282d6SKATO Takenori /* 556a8e282d6SKATO Takenori * OS should flush L1 cahce by itself because no PC-98 supports 557a8e282d6SKATO Takenori * non-Intel CPUs. Use wbinvd instruction before DMA transfer 558a8e282d6SKATO Takenori * when need_pre_dma_flush = 1, use invd instruction after DMA 559a8e282d6SKATO Takenori * transfer when need_post_dma_flush = 1. If your CPU upgrade 560a8e282d6SKATO Takenori * product support hardware cache control, you can add 561a8e282d6SKATO Takenori * UPGRADE_CPU_HW_CACHE option in your kernel configuration file. 562a8e282d6SKATO Takenori * This option elminate unneeded cache flush instruction. 563a8e282d6SKATO Takenori */ 564a8e282d6SKATO Takenori if (strcmp(cpu_vendor, "CyrixInstead") == 0) { 565a8e282d6SKATO Takenori switch (cpu) { 566a8e282d6SKATO Takenori #ifdef I486_CPU 567a8e282d6SKATO Takenori case CPU_486DLC: 568a8e282d6SKATO Takenori need_post_dma_flush = 1; 569a8e282d6SKATO Takenori break; 570a8e282d6SKATO Takenori case CPU_M1SC: 571a8e282d6SKATO Takenori need_pre_dma_flush = 1; 572a8e282d6SKATO Takenori break; 5731cfd836fSKATO Takenori case CPU_CY486DX: 5741cfd836fSKATO Takenori need_pre_dma_flush = 1; 5751cfd836fSKATO Takenori #ifdef CPU_I486_ON_386 5761cfd836fSKATO Takenori need_post_dma_flush = 1; 5771cfd836fSKATO Takenori #endif 5781cfd836fSKATO Takenori break; 579a8e282d6SKATO Takenori #endif 580a8e282d6SKATO Takenori default: 581a8e282d6SKATO Takenori break; 582a8e282d6SKATO Takenori } 583a8e282d6SKATO Takenori } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { 584a8e282d6SKATO Takenori switch (cpu_id & 0xFF0) { 585a8e282d6SKATO Takenori case 0x470: /* Enhanced Am486DX2 WB */ 586a8e282d6SKATO Takenori case 0x490: /* Enhanced Am486DX4 WB */ 587a8e282d6SKATO Takenori case 0x4F0: /* Am5x86 WB */ 588a8e282d6SKATO Takenori need_pre_dma_flush = 1; 589a8e282d6SKATO Takenori break; 590a8e282d6SKATO Takenori } 591a8e282d6SKATO Takenori } else if (strcmp(cpu_vendor, "IBM") == 0) { 592a8e282d6SKATO Takenori need_post_dma_flush = 1; 593a8e282d6SKATO Takenori } else { 594a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386 595a8e282d6SKATO Takenori need_pre_dma_flush = 1; 596a8e282d6SKATO Takenori #endif 597a8e282d6SKATO Takenori } 598a8e282d6SKATO Takenori #endif /* PC98 && !UPGRADE_CPU_HW_CACHE */ 599a8e282d6SKATO Takenori } 600a8e282d6SKATO Takenori 6014536af6aSKATO Takenori #if defined(I586_CPU) && defined(CPU_WT_ALLOC) 6024536af6aSKATO Takenori /* 6034536af6aSKATO Takenori * Enable write allocate feature of AMD processors. 6044536af6aSKATO Takenori * Following two functions require the Maxmem variable being set. 6054536af6aSKATO Takenori */ 6064536af6aSKATO Takenori void 6074536af6aSKATO Takenori enable_K5_wt_alloc(void) 6084536af6aSKATO Takenori { 6094536af6aSKATO Takenori u_int64_t msr; 6104536af6aSKATO Takenori 6114536af6aSKATO Takenori /* 6124536af6aSKATO Takenori * Write allocate is supported only on models 1, 2, and 3, with 6134536af6aSKATO Takenori * a stepping of 4 or greater. 6144536af6aSKATO Takenori */ 6154536af6aSKATO Takenori if (((cpu_id & 0xf0) > 0) && ((cpu_id & 0x0f) > 3)) { 6164536af6aSKATO Takenori disable_intr(); 6174536af6aSKATO Takenori msr = rdmsr(0x83); /* HWCR */ 6184536af6aSKATO Takenori wrmsr(0x83, msr & !(0x10)); 6194536af6aSKATO Takenori 6204536af6aSKATO Takenori /* 6214536af6aSKATO Takenori * We have to tell the chip where the top of memory is, 6224536af6aSKATO Takenori * since video cards could have frame bufferes there, 6234536af6aSKATO Takenori * memory-mapped I/O could be there, etc. 6244536af6aSKATO Takenori */ 6254536af6aSKATO Takenori if(Maxmem > 0) 6264536af6aSKATO Takenori msr = Maxmem / 16; 6274536af6aSKATO Takenori else 6284536af6aSKATO Takenori msr = 0; 6294536af6aSKATO Takenori msr |= AMD_WT_ALLOC_TME | AMD_WT_ALLOC_FRE; 6304536af6aSKATO Takenori #ifdef PC98 6314536af6aSKATO Takenori if (!(inb(0x43b) & 4)) { 6324536af6aSKATO Takenori wrmsr(0x86, 0x0ff00f0); 6334536af6aSKATO Takenori msr |= AMD_WT_ALLOC_PRE; 6344536af6aSKATO Takenori } 6354536af6aSKATO Takenori #else 6364536af6aSKATO Takenori /* 6374536af6aSKATO Takenori * There is no way to know wheter 15-16M hole exists or not. 6384536af6aSKATO Takenori * Therefore, we disable write allocate for this range. 6394536af6aSKATO Takenori */ 6404536af6aSKATO Takenori wrmsr(0x86, 0x0ff00f0); 6414536af6aSKATO Takenori msr |= AMD_WT_ALLOC_PRE; 6424536af6aSKATO Takenori #endif 6434536af6aSKATO Takenori wrmsr(0x85, msr); 6444536af6aSKATO Takenori 6454536af6aSKATO Takenori msr=rdmsr(0x83); 6464536af6aSKATO Takenori wrmsr(0x83, msr|0x10); /* enable write allocate */ 6474536af6aSKATO Takenori 6484536af6aSKATO Takenori enable_intr(); 6494536af6aSKATO Takenori } 6504536af6aSKATO Takenori } 6514536af6aSKATO Takenori 6524536af6aSKATO Takenori void 6534536af6aSKATO Takenori enable_K6_wt_alloc(void) 6544536af6aSKATO Takenori { 6554536af6aSKATO Takenori quad_t size; 6564536af6aSKATO Takenori u_int64_t whcr; 6574536af6aSKATO Takenori u_long eflags; 6584536af6aSKATO Takenori 6594536af6aSKATO Takenori eflags = read_eflags(); 6604536af6aSKATO Takenori disable_intr(); 6614536af6aSKATO Takenori wbinvd(); 6624536af6aSKATO Takenori 6634536af6aSKATO Takenori #ifdef CPU_DISABLE_CACHE 6644536af6aSKATO Takenori /* 6654536af6aSKATO Takenori * Certain K6-2 box becomes unstable when write allocation is 6664536af6aSKATO Takenori * enabled. 6674536af6aSKATO Takenori */ 6684536af6aSKATO Takenori /* 6694536af6aSKATO Takenori * The AMD-K6 processer provides the 64-bit Test Register 12(TR12), 6704536af6aSKATO Takenori * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported. 6714536af6aSKATO Takenori * All other bits in TR12 have no effect on the processer's operation. 6724536af6aSKATO Takenori * The I/O Trap Restart function (bit 9 of TR12) is always enabled 6734536af6aSKATO Takenori * on the AMD-K6. 6744536af6aSKATO Takenori */ 6754536af6aSKATO Takenori wrmsr(0x0000000e, (u_int64_t)0x0008); 6764536af6aSKATO Takenori #endif 6774536af6aSKATO Takenori /* Don't assume that memory size is aligned with 4M. */ 6784536af6aSKATO Takenori if (Maxmem > 0) 6794b055742SKATO Takenori size = ((Maxmem >> 8) + 3) >> 2; 6804536af6aSKATO Takenori else 6814536af6aSKATO Takenori size = 0; 6824536af6aSKATO Takenori 6834536af6aSKATO Takenori /* Limit is 508M bytes. */ 6844b055742SKATO Takenori if (size > 0x7f) 6854b055742SKATO Takenori size = 0x7f; 6864b055742SKATO Takenori whcr = (rdmsr(0xc0000082) & ~(0x7fLL << 1)) | (size << 1); 6874536af6aSKATO Takenori 688925f3681SMike Smith #if defined(PC98) || defined(NO_MEMORY_HOLE) 6894b055742SKATO Takenori if (whcr & (0x7fLL << 1)) { 690925f3681SMike Smith #ifdef PC98 6914536af6aSKATO Takenori /* 6924536af6aSKATO Takenori * If bit 2 of port 0x43b is 0, disable wrte allocate for the 6934536af6aSKATO Takenori * 15-16M range. 6944536af6aSKATO Takenori */ 6954536af6aSKATO Takenori if (!(inb(0x43b) & 4)) 6964536af6aSKATO Takenori whcr &= ~0x0001LL; 6974536af6aSKATO Takenori else 698925f3681SMike Smith #endif 6994536af6aSKATO Takenori whcr |= 0x0001LL; 7004536af6aSKATO Takenori } 7014536af6aSKATO Takenori #else 7024536af6aSKATO Takenori /* 7034536af6aSKATO Takenori * There is no way to know wheter 15-16M hole exists or not. 7044536af6aSKATO Takenori * Therefore, we disable write allocate for this range. 7054536af6aSKATO Takenori */ 706925f3681SMike Smith whcr &= ~0x0001LL; 707925f3681SMike Smith #endif 708925f3681SMike Smith wrmsr(0x0c0000082, whcr); 709925f3681SMike Smith 710925f3681SMike Smith write_eflags(eflags); 711925f3681SMike Smith enable_intr(); 712925f3681SMike Smith } 713925f3681SMike Smith 714925f3681SMike Smith void 715925f3681SMike Smith enable_K6_2_wt_alloc(void) 716925f3681SMike Smith { 717925f3681SMike Smith quad_t size; 718925f3681SMike Smith u_int64_t whcr; 719925f3681SMike Smith u_long eflags; 720925f3681SMike Smith 721925f3681SMike Smith eflags = read_eflags(); 722925f3681SMike Smith disable_intr(); 723925f3681SMike Smith wbinvd(); 724925f3681SMike Smith 725925f3681SMike Smith #ifdef CPU_DISABLE_CACHE 726925f3681SMike Smith /* 727925f3681SMike Smith * Certain K6-2 box becomes unstable when write allocation is 728925f3681SMike Smith * enabled. 729925f3681SMike Smith */ 730925f3681SMike Smith /* 731925f3681SMike Smith * The AMD-K6 processer provides the 64-bit Test Register 12(TR12), 732925f3681SMike Smith * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported. 733925f3681SMike Smith * All other bits in TR12 have no effect on the processer's operation. 734925f3681SMike Smith * The I/O Trap Restart function (bit 9 of TR12) is always enabled 735925f3681SMike Smith * on the AMD-K6. 736925f3681SMike Smith */ 737925f3681SMike Smith wrmsr(0x0000000e, (u_int64_t)0x0008); 738925f3681SMike Smith #endif 739925f3681SMike Smith /* Don't assume that memory size is aligned with 4M. */ 740925f3681SMike Smith if (Maxmem > 0) 741925f3681SMike Smith size = ((Maxmem >> 8) + 3) >> 2; 742925f3681SMike Smith else 743925f3681SMike Smith size = 0; 744925f3681SMike Smith 745925f3681SMike Smith /* Limit is 4092M bytes. */ 7464b055742SKATO Takenori if (size > 0x3fff) 7474b055742SKATO Takenori size = 0x3ff; 748925f3681SMike Smith whcr = (rdmsr(0xc0000082) & ~(0x3ffLL << 22)) | (size << 22); 749925f3681SMike Smith 750925f3681SMike Smith #if defined(PC98) || defined(NO_MEMORY_HOLE) 751925f3681SMike Smith if (whcr & (0x3ffLL << 22)) { 752925f3681SMike Smith #ifdef PC98 753925f3681SMike Smith /* 754925f3681SMike Smith * If bit 2 of port 0x43b is 0, disable wrte allocate for the 755925f3681SMike Smith * 15-16M range. 756925f3681SMike Smith */ 757925f3681SMike Smith if (!(inb(0x43b) & 4)) 758925f3681SMike Smith whcr &= ~(1LL << 16); 759925f3681SMike Smith else 760925f3681SMike Smith #endif 761925f3681SMike Smith whcr |= 1LL << 16; 762925f3681SMike Smith } 763925f3681SMike Smith #else 764925f3681SMike Smith /* 765925f3681SMike Smith * There is no way to know wheter 15-16M hole exists or not. 766925f3681SMike Smith * Therefore, we disable write allocate for this range. 767925f3681SMike Smith */ 768925f3681SMike Smith whcr &= ~(1LL << 16); 7694536af6aSKATO Takenori #endif 7704536af6aSKATO Takenori wrmsr(0x0c0000082, whcr); 7714536af6aSKATO Takenori 7724536af6aSKATO Takenori write_eflags(eflags); 7734536af6aSKATO Takenori enable_intr(); 7744536af6aSKATO Takenori } 7754536af6aSKATO Takenori #endif /* I585_CPU && CPU_WT_ALLOC */ 7764536af6aSKATO Takenori 777a8e282d6SKATO Takenori #include "opt_ddb.h" 778a8e282d6SKATO Takenori #ifdef DDB 779a8e282d6SKATO Takenori #include <ddb/ddb.h> 780a8e282d6SKATO Takenori 781a8e282d6SKATO Takenori DB_SHOW_COMMAND(cyrixreg, cyrixreg) 782a8e282d6SKATO Takenori { 783a8e282d6SKATO Takenori u_long eflags; 784a8e282d6SKATO Takenori u_int cr0; 7859402b520SMatthew Dillon u_char ccr1, ccr2, ccr3; 7869402b520SMatthew Dillon u_char ccr0 = 0, ccr4 = 0, ccr5 = 0, pcr0 = 0; 787a8e282d6SKATO Takenori 788a8e282d6SKATO Takenori cr0 = rcr0(); 789a8e282d6SKATO Takenori if (strcmp(cpu_vendor,"CyrixInstead") == 0) { 790a8e282d6SKATO Takenori eflags = read_eflags(); 791a8e282d6SKATO Takenori disable_intr(); 792a8e282d6SKATO Takenori 793a8e282d6SKATO Takenori 7949ca82267SKATO Takenori if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) { 795a8e282d6SKATO Takenori ccr0 = read_cyrix_reg(CCR0); 796a8e282d6SKATO Takenori } 797a8e282d6SKATO Takenori ccr1 = read_cyrix_reg(CCR1); 798a8e282d6SKATO Takenori ccr2 = read_cyrix_reg(CCR2); 799a8e282d6SKATO Takenori ccr3 = read_cyrix_reg(CCR3); 8006593be60SKATO Takenori if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) { 801a8e282d6SKATO Takenori write_cyrix_reg(CCR3, CCR3_MAPEN0); 802a8e282d6SKATO Takenori ccr4 = read_cyrix_reg(CCR4); 8036593be60SKATO Takenori if ((cpu == CPU_M1) || (cpu == CPU_M2)) 804a8e282d6SKATO Takenori ccr5 = read_cyrix_reg(CCR5); 805a8e282d6SKATO Takenori else 806a8e282d6SKATO Takenori pcr0 = read_cyrix_reg(PCR0); 807a8e282d6SKATO Takenori write_cyrix_reg(CCR3, ccr3); /* Restore CCR3. */ 808a8e282d6SKATO Takenori } 809a8e282d6SKATO Takenori write_eflags(eflags); 810a8e282d6SKATO Takenori 8119ca82267SKATO Takenori if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) 812a8e282d6SKATO Takenori printf("CCR0=%x, ", (u_int)ccr0); 813a8e282d6SKATO Takenori 814a8e282d6SKATO Takenori printf("CCR1=%x, CCR2=%x, CCR3=%x", 815a8e282d6SKATO Takenori (u_int)ccr1, (u_int)ccr2, (u_int)ccr3); 8166593be60SKATO Takenori if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) { 817a8e282d6SKATO Takenori printf(", CCR4=%x, ", (u_int)ccr4); 8186593be60SKATO Takenori if (cpu == CPU_M1SC) 819a8e282d6SKATO Takenori printf("PCR0=%x\n", pcr0); 8206593be60SKATO Takenori else 8216593be60SKATO Takenori printf("CCR5=%x\n", ccr5); 822a8e282d6SKATO Takenori } 823a8e282d6SKATO Takenori } 824a8e282d6SKATO Takenori printf("CR0=%x\n", cr0); 825a8e282d6SKATO Takenori } 826a8e282d6SKATO Takenori #endif /* DDB */ 827